Preguntas de Entrevista Laravel 2026: Eloquent, Queues y Patrones de Arquitectura
Guía completa de preguntas técnicas de entrevista Laravel en 2026. Domina Eloquent ORM, queues, patrones de arquitectura y mejores prácticas para tu próxima entrevista de trabajo.

En 2026, Laravel continúa siendo el framework PHP más utilizado para el desarrollo de aplicaciones web empresariales. Con el lanzamiento de Laravel 12 y las constantes mejoras del ecosistema, los reclutadores esperan que los candidatos demuestren un dominio profundo de Eloquent ORM, sistemas de queues y patrones de arquitectura modernos. Este artículo presenta las preguntas más frecuentes en entrevistas técnicas de Laravel, acompañadas de ejemplos de código prácticos y explicaciones detalladas.
Las empresas buscan desarrolladores Laravel capaces de diseñar aplicaciones escalables y mantenibles. Más allá de la sintaxis, es fundamental demostrar comprensión de los conceptos subyacentes: el ciclo de vida de las peticiones, la inyección de dependencias, el Service Container y los patrones de diseño. Los candidatos exitosos son aquellos que pueden explicar el "por qué" detrás de cada decisión técnica.
Eloquent ORM: Preguntas avanzadas sobre relaciones
Eloquent está en el núcleo de Laravel y generalmente es el primer tema que se aborda en las entrevistas. Los reclutadores evalúan la capacidad de optimizar consultas y evitar problemas de rendimiento comunes.
¿Cómo se resuelve el problema de N+1 queries?
El problema N+1 ocurre cuando el código ejecuta una consulta adicional por cada elemento de una colección. Esta situación puede degradar rápidamente el rendimiento de la aplicación.
// Problema N+1: Una consulta para posts + N consultas para autores
$posts = Post::all();
foreach ($posts as $post) {
echo $post->author->name; // Consulta adicional en cada iteración
}
// Solución: Eager Loading con with()
$posts = Post::with('author')->get();
foreach ($posts as $post) {
echo $post->author->name; // Sin consultas adicionales
}
// Eager Loading condicional para necesidades específicas
$posts = Post::with(['author' => function ($query) {
$query->select('id', 'name', 'email');
}])->get();
// Eager Loading anidado para relaciones múltiples
$posts = Post::with(['author.profile', 'comments.user'])->get();El uso de with() permite cargar las relaciones en solo dos consultas, independientemente del tamaño de la colección. Para aplicaciones críticas, activar Model::preventLazyLoading() en desarrollo permite detectar automáticamente estos problemas.
Explica la diferencia entre hasOne, hasMany, belongsTo y belongsToMany
La comprensión de las relaciones Eloquent es fundamental para modelar correctamente una base de datos.
class User extends Model
{
// Un usuario tiene un perfil (1:1)
public function profile(): HasOne
{
return $this->hasOne(Profile::class);
}
// Un usuario puede tener varios artículos (1:N)
public function posts(): HasMany
{
return $this->hasMany(Post::class);
}
// Un usuario puede tener varios roles (N:N)
public function roles(): BelongsToMany
{
return $this->belongsToMany(Role::class)
->withPivot('assigned_at')
->withTimestamps();
}
}
class Post extends Model
{
// Un artículo pertenece a un usuario
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
// Relación polimórfica: un artículo puede tener comentarios
public function comments(): MorphMany
{
return $this->morphMany(Comment::class, 'commentable');
}
}¿Cómo crear Query Scopes reutilizables?
Los scopes permiten encapsular la lógica de consulta para reutilizarla en toda la aplicación.
class Post extends Model
{
// Scope local: filtrar artículos publicados
public function scopePublished(Builder $query): Builder
{
return $query->whereNotNull('published_at')
->where('published_at', '<=', now());
}
// Scope con parámetro
public function scopeByAuthor(Builder $query, int $authorId): Builder
{
return $query->where('author_id', $authorId);
}
// Scope dinámico basado en una condición
public function scopePopular(Builder $query, int $minViews = 1000): Builder
{
return $query->where('views_count', '>=', $minViews)
->orderByDesc('views_count');
}
}
// Uso encadenado de scopes
$trendingPosts = Post::published()
->popular(5000)
->with('author')
->limit(10)
->get();Sistema de Queues: Procesamiento asíncrono y Jobs
Las queues son esenciales para mantener tiempos de respuesta rápidos delegando tareas pesadas a workers en segundo plano.
¿Cómo crear y despachar un Job?
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
{
// Procesamiento del archivo de audio
$processor->normalize($this->filePath);
$processor->generateWaveform($this->filePath);
// Actualización del estado
$this->podcast->update(['status' => 'processed']);
// Notificación al usuario
$this->podcast->author->notify(new PodcastProcessed($this->podcast));
}
// Manejo de fallos
public function failed(Throwable $exception): void
{
$this->podcast->update(['status' => 'failed']);
Log::error('Podcast processing failed', [
'podcast_id' => $this->podcast->id,
'error' => $exception->getMessage()
]);
}
// Configuración de reintentos
public int $tries = 3;
public int $backoff = 60; // Segundos entre intentos
}
// Despacho del job
ProcessPodcastUpload::dispatch($podcast, $filePath)
->onQueue('audio-processing')
->delay(now()->addMinutes(5));¿Cómo manejar Job Batches y cadenas de jobs?
Laravel permite agrupar varios jobs y monitorear su progreso.
use Illuminate\Bus\Batch;
use Illuminate\Support\Facades\Bus;
// Creación de un batch de jobs
$batch = Bus::batch([
new ProcessImage($image1),
new ProcessImage($image2),
new ProcessImage($image3),
])->then(function (Batch $batch) {
// Todos los jobs completados exitosamente
Log::info('Batch completed successfully');
})->catch(function (Batch $batch, Throwable $e) {
// Primer fallo detectado
Log::error('Batch failed', ['error' => $e->getMessage()]);
})->finally(function (Batch $batch) {
// Ejecutado en todos los casos
Cache::forget('image-processing-status');
})->onQueue('images')
->dispatch();
// Cadena de jobs secuenciales
Bus::chain([
new ExtractVideoFrames($video),
new GenerateThumbnails($video),
new NotifyUser($video->user),
])->onQueue('video-processing')
->dispatch();Patrones de Arquitectura: Service Layer y Repository Pattern
Los patrones de arquitectura permiten estructurar el código de manera mantenible y testeable.
¿Cómo implementar el Repository Pattern?
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 en AppServiceProvider
public function register(): void
{
$this->app->bind(
UserRepositoryInterface::class,
EloquentUserRepository::class
);
}¿Cómo estructurar un Service Layer efectivo?
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) {
// Verificación de stock
foreach ($items as $item) {
if (!$this->inventoryService->checkAvailability($item['product_id'], $item['quantity'])) {
throw new InsufficientStockException($item['product_id']);
}
}
// Creación del pedido
$order = $this->orderRepository->create([
'user_id' => $user->id,
'status' => OrderStatus::PENDING,
'total' => $this->calculateTotal($items),
]);
// Agregar líneas del pedido
foreach ($items as $item) {
$order->items()->create($item);
$this->inventoryService->reserve($item['product_id'], $item['quantity']);
}
// Evento de creación
event(new OrderCreated($order));
return $order;
});
}
private function calculateTotal(array $items): float
{
return collect($items)->sum(fn ($item) => $item['price'] * $item['quantity']);
}
}Middleware y Request Lifecycle
Comprender el ciclo de vida de una petición es esencial para depurar y optimizar aplicaciones Laravel.
¿Cómo crear un Middleware personalizado?
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);
}
// Agregar la versión al contexto de la petición
$request->attributes->set('api_version', $requestedVersion);
$response = $next($request);
// Agregar headers de respuesta
return $response->withHeaders([
'X-API-Version' => $requestedVersion,
'X-RateLimit-Remaining' => RateLimiter::remaining($request->ip(), 60)
]);
}
}
// Registro en bootstrap/app.php (Laravel 11+)
return Application::configure(basePath: dirname(__DIR__))
->withMiddleware(function (Middleware $middleware) {
$middleware->alias([
'api.version' => EnsureApiVersion::class,
]);
});Tests: Mejores prácticas para aplicaciones Laravel
Los tests son un tema frecuente en entrevistas, ya que demuestran un enfoque profesional del desarrollo.
¿Cómo testear un Controller con dependencias?
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 del servicio de pago
$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']);
}
}¿Listo para aprobar tus entrevistas de Laravel?
Practica con nuestros simuladores interactivos, flashcards y tests técnicos.
Preguntas conceptuales comunes
Más allá del código, los reclutadores evalúan la comprensión de conceptos fundamentales.
Explica el Service Container y la inyección de dependencias
El Service Container de Laravel es un contenedor de inversión de control (IoC) que gestiona las dependencias de las clases. Cuando una clase necesita una dependencia, el container la resuelve automáticamente.
// Resolución automática por type-hinting
class ReportController extends Controller
{
public function __construct(
private readonly ReportGenerator $generator, // Resuelto automáticamente
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 instancias compartidas
$this->app->singleton(MetricsCollector::class, function ($app) {
return new MetricsCollector(
$app->make(RedisConnection::class)
);
});¿Cómo optimizar el rendimiento de una aplicación Laravel?
La optimización del rendimiento abarca varios aspectos:
// php artisan config:cache
// php artisan route:cache
// php artisan view:cache
// 2. Uso de cache para datos frecuentemente accedidos
$users = Cache::remember('active-users', 3600, function () {
return User::where('active', true)
->with('profile')
->get();
});
// 3. Paginación para grandes colecciones
$posts = Post::with('author')
->published()
->cursorPaginate(20); // Más eficiente que paginate() para grandes datasets
// 4. Índices de base de datos en migraciones
Schema::table('posts', function (Blueprint $table) {
$table->index(['published_at', 'author_id']);
$table->index('status');
});
// 5. Chunking para procesamiento masivo
User::where('newsletter', true)
->chunkById(1000, function ($users) {
foreach ($users as $user) {
SendNewsletter::dispatch($user);
}
});Conclusión
La preparación para entrevistas Laravel en 2026 requiere un dominio profundo de Eloquent ORM, sistemas de queues y patrones de arquitectura. Los reclutadores buscan desarrolladores capaces de escribir código eficiente, mantenible y testeable. La práctica regular con proyectos reales sigue siendo la mejor manera de consolidar estos conocimientos. Se recomienda contribuir a proyectos open source y explorar las nuevas funcionalidades de Laravel 12 para mantenerse actualizado con la evolución del framework.
¿Sabrías detectar el bug en Laravel?
Un fragmento real, un bug oculto, un intento al día. Sin cuenta para probar.

Escrito por
Anthony Fillion-MailletFundador de SharpSkill
Desarrollador fullstack desde hace más de 10 años. Dirige SharpSkill y responde por todo lo que se publica aquí.
Actualizado el 16 de septiembre de 2026
Etiquetas
Compartir
Artículos relacionados

Eloquent ORM: patrones y optimizaciones para Laravel
Domina Eloquent ORM con patrones avanzados y técnicas de optimización. Eager loading, query scopes, accessors, mutators y rendimiento para aplicaciones Laravel.

Preguntas de Entrevista sobre Laravel y PHP: Las 25 Principales en 2026
Las 25 preguntas mas comunes en entrevistas sobre Laravel y PHP. Eloquent ORM, middleware, artisan, colas, tests y arquitectura con respuestas detalladas y ejemplos de codigo.

Laravel 11: Construir una Aplicacion Completa desde Cero
Guia completa para construir una aplicacion con Laravel 11: autenticacion, API REST, Eloquent ORM y despliegue a produccion. Tutorial practico para desarrolladores principiantes e intermedios.