Perguntas de Entrevista Laravel 2026: Eloquent, Queues e Padrões de Arquitetura

Guia completo de perguntas técnicas para entrevistas Laravel em 2026. Domine Eloquent ORM, queues, padrões de arquitetura e melhores práticas para sua próxima entrevista de emprego.

Perguntas de Entrevista Laravel 2026

Em 2026, Laravel continua sendo o framework PHP mais utilizado para desenvolvimento de aplicações web corporativas. Com o lançamento do Laravel 12 e a evolução constante do ecossistema, os recrutadores esperam que os candidatos demonstrem domínio profundo do Eloquent ORM, sistemas de queues e padrões de arquitetura modernos. Este artigo apresenta as perguntas mais frequentes em entrevistas técnicas de Laravel, acompanhadas de exemplos de código práticos e explicações detalhadas.

O que os recrutadores procuram

As empresas buscam desenvolvedores Laravel capazes de projetar aplicações escaláveis e manuteníveis. Além da sintaxe, é fundamental demonstrar compreensão dos conceitos subjacentes: o ciclo de vida das requisições, injeção de dependências, Service Container e padrões de design. Os candidatos bem-sucedidos são aqueles que conseguem explicar o "porquê" por trás de cada decisão técnica.

Eloquent ORM: Perguntas avançadas sobre relacionamentos

O Eloquent está no núcleo do Laravel e geralmente é o primeiro tema abordado nas entrevistas. Os recrutadores avaliam a capacidade de otimizar consultas e evitar problemas de performance comuns.

Como resolver o problema de N+1 queries?

O problema N+1 ocorre quando o código executa uma consulta adicional para cada elemento de uma coleção. Esta situação pode degradar rapidamente a performance da aplicação.

php
// Problema N+1: Uma consulta para posts + N consultas para autores
$posts = Post::all();
foreach ($posts as $post) {
    echo $post->author->name; // Consulta adicional em cada iteração
}

// Solução: Eager Loading com with()
$posts = Post::with('author')->get();
foreach ($posts as $post) {
    echo $post->author->name; // Sem consultas adicionais
}

// Eager Loading condicional para necessidades específicas
$posts = Post::with(['author' => function ($query) {
    $query->select('id', 'name', 'email');
}])->get();

// Eager Loading aninhado para relacionamentos múltiplos
$posts = Post::with(['author.profile', 'comments.user'])->get();

O uso de with() permite carregar os relacionamentos em apenas duas consultas, independentemente do tamanho da coleção. Para aplicações críticas, ativar Model::preventLazyLoading() em desenvolvimento permite detectar automaticamente estes problemas.

Explique a diferença entre hasOne, hasMany, belongsTo e belongsToMany

A compreensão dos relacionamentos Eloquent é fundamental para modelar corretamente um banco de dados.

php
class User extends Model
{
    // Um usuário possui um perfil (1:1)
    public function profile(): HasOne
    {
        return $this->hasOne(Profile::class);
    }

    // Um usuário pode ter vários artigos (1:N)
    public function posts(): HasMany
    {
        return $this->hasMany(Post::class);
    }

    // Um usuário pode ter vários papéis (N:N)
    public function roles(): BelongsToMany
    {
        return $this->belongsToMany(Role::class)
            ->withPivot('assigned_at')
            ->withTimestamps();
    }
}

class Post extends Model
{
    // Um artigo pertence a um usuário
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    // Relacionamento polimórfico: um artigo pode ter comentários
    public function comments(): MorphMany
    {
        return $this->morphMany(Comment::class, 'commentable');
    }
}

Como criar Query Scopes reutilizáveis?

Os scopes permitem encapsular a lógica de consulta para reutilizá-la em toda a aplicação.

php
class Post extends Model
{
    // Scope local: filtrar artigos publicados
    public function scopePublished(Builder $query): Builder
    {
        return $query->whereNotNull('published_at')
            ->where('published_at', '<=', now());
    }

    // Scope com parâmetro
    public function scopeByAuthor(Builder $query, int $authorId): Builder
    {
        return $query->where('author_id', $authorId);
    }

    // Scope dinâmico baseado em uma condição
    public function scopePopular(Builder $query, int $minViews = 1000): Builder
    {
        return $query->where('views_count', '>=', $minViews)
            ->orderByDesc('views_count');
    }
}

// Uso encadeado de scopes
$trendingPosts = Post::published()
    ->popular(5000)
    ->with('author')
    ->limit(10)
    ->get();

Sistema de Queues: Processamento assíncrono e Jobs

As queues são essenciais para manter tempos de resposta rápidos delegando tarefas pesadas para workers em segundo plano.

Como criar e despachar um Job?

app/Jobs/ProcessPodcastUpload.phpphp
class ProcessPodcastUpload implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function __construct(
        public readonly Podcast $podcast,
        public readonly string $filePath
    ) {}

    public function handle(AudioProcessor $processor): void
    {
        // Processamento do arquivo de áudio
        $processor->normalize($this->filePath);
        $processor->generateWaveform($this->filePath);
        
        // Atualização do status
        $this->podcast->update(['status' => 'processed']);
        
        // Notificação ao usuário
        $this->podcast->author->notify(new PodcastProcessed($this->podcast));
    }

    // Tratamento de falhas
    public function failed(Throwable $exception): void
    {
        $this->podcast->update(['status' => 'failed']);
        Log::error('Podcast processing failed', [
            'podcast_id' => $this->podcast->id,
            'error' => $exception->getMessage()
        ]);
    }

    // Configuração de tentativas
    public int $tries = 3;
    public int $backoff = 60; // Segundos entre tentativas
}

// Despacho do job
ProcessPodcastUpload::dispatch($podcast, $filePath)
    ->onQueue('audio-processing')
    ->delay(now()->addMinutes(5));

Como gerenciar Job Batches e cadeias de jobs?

O Laravel permite agrupar vários jobs e monitorar seu progresso.

php
use Illuminate\Bus\Batch;
use Illuminate\Support\Facades\Bus;

// Criação de um batch de jobs
$batch = Bus::batch([
    new ProcessImage($image1),
    new ProcessImage($image2),
    new ProcessImage($image3),
])->then(function (Batch $batch) {
    // Todos os jobs completados com sucesso
    Log::info('Batch completed successfully');
})->catch(function (Batch $batch, Throwable $e) {
    // Primeira falha detectada
    Log::error('Batch failed', ['error' => $e->getMessage()]);
})->finally(function (Batch $batch) {
    // Executado em todos os casos
    Cache::forget('image-processing-status');
})->onQueue('images')
  ->dispatch();

// Cadeia de jobs sequenciais
Bus::chain([
    new ExtractVideoFrames($video),
    new GenerateThumbnails($video),
    new NotifyUser($video->user),
])->onQueue('video-processing')
  ->dispatch();

Padrões de Arquitetura: Service Layer e Repository Pattern

Os padrões de arquitetura permitem estruturar o código de maneira manutenível e testável.

Como implementar o Repository Pattern?

app/Repositories/Contracts/UserRepositoryInterface.phpphp
interface UserRepositoryInterface
{
    public function find(int $id): ?User;
    public function findByEmail(string $email): ?User;
    public function create(array $data): User;
    public function update(int $id, array $data): bool;
    public function delete(int $id): bool;
    public function paginate(int $perPage = 15): LengthAwarePaginator;
}

// app/Repositories/EloquentUserRepository.php
class EloquentUserRepository implements UserRepositoryInterface
{
    public function __construct(
        private readonly User $model
    ) {}

    public function find(int $id): ?User
    {
        return $this->model->find($id);
    }

    public function findByEmail(string $email): ?User
    {
        return $this->model->where('email', $email)->first();
    }

    public function create(array $data): User
    {
        return $this->model->create($data);
    }

    public function update(int $id, array $data): bool
    {
        return $this->model->where('id', $id)->update($data) > 0;
    }

    public function delete(int $id): bool
    {
        return $this->model->destroy($id) > 0;
    }

    public function paginate(int $perPage = 15): LengthAwarePaginator
    {
        return $this->model->latest()->paginate($perPage);
    }
}

// Binding no AppServiceProvider
public function register(): void
{
    $this->app->bind(
        UserRepositoryInterface::class,
        EloquentUserRepository::class
    );
}

Como estruturar um Service Layer eficaz?

app/Services/OrderService.phpphp
class OrderService
{
    public function __construct(
        private readonly OrderRepositoryInterface $orderRepository,
        private readonly InventoryService $inventoryService,
        private readonly PaymentGateway $paymentGateway
    ) {}

    public function createOrder(User $user, array $items): Order
    {
        return DB::transaction(function () use ($user, $items) {
            // Verificação de estoque
            foreach ($items as $item) {
                if (!$this->inventoryService->checkAvailability($item['product_id'], $item['quantity'])) {
                    throw new InsufficientStockException($item['product_id']);
                }
            }

            // Criação do pedido
            $order = $this->orderRepository->create([
                'user_id' => $user->id,
                'status' => OrderStatus::PENDING,
                'total' => $this->calculateTotal($items),
            ]);

            // Adicionar itens do pedido
            foreach ($items as $item) {
                $order->items()->create($item);
                $this->inventoryService->reserve($item['product_id'], $item['quantity']);
            }

            // Evento de criação
            event(new OrderCreated($order));

            return $order;
        });
    }

    private function calculateTotal(array $items): float
    {
        return collect($items)->sum(fn ($item) => $item['price'] * $item['quantity']);
    }
}

Middleware e Request Lifecycle

Compreender o ciclo de vida de uma requisição é essencial para depurar e otimizar aplicações Laravel.

Como criar um Middleware personalizado?

app/Http/Middleware/EnsureApiVersion.phpphp
class EnsureApiVersion
{
    public function handle(Request $request, Closure $next, string $version = 'v1'): Response
    {
        $requestedVersion = $request->header('Accept-Version', $version);
        
        if (!in_array($requestedVersion, ['v1', 'v2'])) {
            return response()->json([
                'error' => 'Unsupported API version',
                'supported' => ['v1', 'v2']
            ], 400);
        }

        // Adicionar a versão ao contexto da requisição
        $request->attributes->set('api_version', $requestedVersion);

        $response = $next($request);

        // Adicionar headers de resposta
        return $response->withHeaders([
            'X-API-Version' => $requestedVersion,
            'X-RateLimit-Remaining' => RateLimiter::remaining($request->ip(), 60)
        ]);
    }
}

// Registro em bootstrap/app.php (Laravel 11+)
return Application::configure(basePath: dirname(__DIR__))
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->alias([
            'api.version' => EnsureApiVersion::class,
        ]);
    });

Testes: Melhores práticas para aplicações Laravel

Os testes são um tema frequente em entrevistas, pois demonstram uma abordagem profissional de desenvolvimento.

Como testar um Controller com dependências?

php
class OrderControllerTest extends TestCase
{
    use RefreshDatabase;

    public function test_user_can_create_order(): void
    {
        // Arrange
        $user = User::factory()->create();
        $product = Product::factory()->create(['stock' => 10, 'price' => 99.99]);
        
        // Mock do serviço de pagamento
        $this->mock(PaymentGateway::class, function ($mock) {
            $mock->shouldReceive('charge')
                ->once()
                ->andReturn(new PaymentResult(success: true, transactionId: 'txn_123'));
        });

        // Act
        $response = $this->actingAs($user)
            ->postJson('/api/orders', [
                'items' => [
                    ['product_id' => $product->id, 'quantity' => 2]
                ]
            ]);

        // Assert
        $response->assertStatus(201)
            ->assertJsonStructure([
                'data' => ['id', 'status', 'total', 'items']
            ]);

        $this->assertDatabaseHas('orders', [
            'user_id' => $user->id,
            'status' => 'pending'
        ]);
    }

    public function test_order_fails_with_insufficient_stock(): void
    {
        $user = User::factory()->create();
        $product = Product::factory()->create(['stock' => 1]);

        $response = $this->actingAs($user)
            ->postJson('/api/orders', [
                'items' => [
                    ['product_id' => $product->id, 'quantity' => 5]
                ]
            ]);

        $response->assertStatus(422)
            ->assertJsonValidationErrors(['items.0.quantity']);
    }
}

Pronto para mandar bem nas entrevistas de Laravel?

Pratique com nossos simuladores interativos, flashcards e testes tecnicos.

Perguntas conceituais comuns

Além do código, os recrutadores avaliam a compreensão de conceitos fundamentais.

Explique o Service Container e a injeção de dependências

O Service Container do Laravel é um container de inversão de controle (IoC) que gerencia as dependências das classes. Quando uma classe precisa de uma dependência, o container a resolve automaticamente.

php
// Resolução automática por type-hinting
class ReportController extends Controller
{
    public function __construct(
        private readonly ReportGenerator $generator, // Resolvido automaticamente
        private readonly CacheManager $cache
    ) {}
}

// Binding personalizado para interfaces
$this->app->bind(ReportGeneratorInterface::class, function ($app) {
    return new PdfReportGenerator(
        $app->make(PdfRenderer::class),
        config('reports.default_format')
    );
});

// Singleton para instâncias compartilhadas
$this->app->singleton(MetricsCollector::class, function ($app) {
    return new MetricsCollector(
        $app->make(RedisConnection::class)
    );
});

Como otimizar a performance de uma aplicação Laravel?

A otimização de performance abrange vários aspectos:

1. Cache de configurações e rotasphp
// php artisan config:cache
// php artisan route:cache
// php artisan view:cache

// 2. Uso de cache para dados frequentemente acessados
$users = Cache::remember('active-users', 3600, function () {
    return User::where('active', true)
        ->with('profile')
        ->get();
});

// 3. Paginação para grandes coleções
$posts = Post::with('author')
    ->published()
    ->cursorPaginate(20); // Mais eficiente que paginate() para grandes datasets

// 4. Índices de banco de dados em migrations
Schema::table('posts', function (Blueprint $table) {
    $table->index(['published_at', 'author_id']);
    $table->index('status');
});

// 5. Chunking para processamento em massa
User::where('newsletter', true)
    ->chunkById(1000, function ($users) {
        foreach ($users as $user) {
            SendNewsletter::dispatch($user);
        }
    });

Conclusão

A preparação para entrevistas Laravel em 2026 requer domínio profundo do Eloquent ORM, sistemas de queues e padrões de arquitetura. Os recrutadores buscam desenvolvedores capazes de escrever código eficiente, manutenível e testável. A prática regular com projetos reais continua sendo a melhor maneira de consolidar estes conhecimentos. Recomenda-se contribuir para projetos open source e explorar as novas funcionalidades do Laravel 12 para se manter atualizado com a evolução do framework.

Desafio do dia

Você saberia encontrar o bug em Laravel?

Um trecho real, um bug escondido, uma tentativa por dia. Sem conta para testar.

Anthony Fillion-Maillet

Escrito por

Anthony Fillion-Maillet

Fundador da SharpSkill

Desenvolvedor fullstack há mais de 10 anos. Dirige a SharpSkill e responde por tudo o que é publicado aqui.

Atualizado em 16 de setembro de 2026

Tags

#laravel
#php
#eloquent
#queues
#arquitetura
#entrevista

Compartilhar

Artigos relacionados