Luyện Phỏng Vấn IT — 2000+ Câu Hỏi Phỏng Vấn IT Có Đáp Án 2026
Laravel
Laravel là framework PHP hiện đại với cú pháp thanh lịch và bộ công cụ phong phú cho phép phát triển ứng dụng nhanh.
- Nó giải quyết các vấn đề phổ biến: routing (ánh xạ URL), templating (engine Blade), truy cập database (Eloquent ORM), xác thực, validation, quản lý session và testing.
- Tuân theo mô hình MVC để tách biệt các mối quan tâm.
- Tính năng tích hợp sẵn tiết kiệm thời gian phát triển so với tự viết từ đầu.
- Laravel 11 (2024) đơn giản hóa đáng kể cấu trúc: bỏ
app/Http/Kernel.php, dùngbootstrap/app.phpđể cấu hình middleware; bỏEventServiceProvider,AuthServiceProvider— đăng ký tập trung trongAppServiceProvider.
Routing ánh xạ URL đến controller action.
- Định nghĩa trong
routes/web.php:Route::get("/users", [UserController::class, "index"])ánh xạ GET request đến /users vào method index của UserController. - Các method khác:
Route::post(),Route::put(),Route::delete(). - Route parameter:
Route::get("/users/{id}", ...)bắt segment URL. - Route name:
Route::get(...)->name("users.show")cho phép tạo link bằngroute("users.show", ["id" => 1]). - Middleware:
Route::get(...)->middleware("auth")thêm kiểm tra xác thực. - Laravel 11+ không còn
$routeMiddlewaretrong Kernel.php — dùng->middleware("alias")trực tiếp trên route.
Blade là engine template đơn giản nhưng mạnh mẽ của Laravel. Biên dịch cú pháp mustache {{ }} thành code PHP, được cache để tăng hiệu suất. Các directive quan trọng: {{ $variable }} in biến (đã escape), {!! $html !!} in HTML thô, @if, @foreach, @for cho cấu trúc điều khiển, @include("template") nhúng view khác, @yield("content") trong layouts.
Ví dụ: @foreach($users as $user) <p>{{ $user->name }}</p> @endforeach. Blade tách biệt trình bày khỏi logic, cải thiện khả năng bảo trì và dễ đọc.
Migration là định nghĩa schema database được quản lý bằng version control. Tạo bằng php artisan make:migration create_users_table. Định nghĩa bảng trong method up(): Schema::create("users", function(Blueprint $table) { $table->id(); $table->string("name"); ... }) và rollback trong down(). Chạy tất cả migration bằng php artisan migrate.
Ưu điểm: theo dõi thay đổi schema trong git, rollback dễ dàng, nhất quán giữa các môi trường, tài liệu hóa cấu trúc bảng. Migration giải quyết vấn đề đồng bộ database trong team và khi deploy. Lưu ý: dùng $table->id() (Laravel 11 convention, tương đương bigIncrements) thay vì $table->increments("id") cũ.
MVC tách biệt các mối quan tâm: Model (logic dữ liệu/database), View (giao diện/UI), Controller (xử lý request/logic nghiệp vụ). Request của người dùng đi đến Router, gọi Controller thích hợp. Controller truy vấn Model lấy dữ liệu, rồi render View với dữ liệu đó.
Ví dụ: GET /users → UsersController@index → User::all() → view("users.index", ["users" => $users]). Việc tách biệt cho phép developer làm việc độc lập, cải thiện khả năng test, và bảo trì code. Cấu trúc thư mục của Laravel (app/Models, resources/views, app/Http/Controllers) thực thi MVC.
Artisan là giao diện dòng lệnh của Laravel để tự động hóa các tác vụ phổ biến.
- Các lệnh thiết yếu:
php artisan migrate(chạy migration),php artisan make:controller UserController(tạo controller),php artisan make:model User(tạo model),php artisan serve(khởi động server dev),php artisan tinker(shell tương tác để test),php artisan route:list(xem tất cả route),php artisan cache:clear(xóa cache). - Artisan tiết kiệm thời gian bằng cách tự động hóa các tác vụ lặp đi lặp lại và đảm bảo tính nhất quán trong việc tạo code.
Controller xử lý logic request, thường tương ứng với một resource (User, Product). Tạo bằng php artisan make:controller ProductController --resource sinh ra các method CRUD: index() (hiển thị tất cả), show($id) (hiển thị một), create() (hiển thị form tạo), store() (lưu từ form), edit() (hiển thị form sửa), update() (lưu sửa đổi), destroy() (xóa). Controller xử lý request, tương tác với Model, và trả về View hay JSON.
Ví dụ: public function store(Request $request) { $product = Product::create($request->validated()); return redirect()->route("products.show", $product); }. Luôn dùng $request->validated() thay vì $request->all() để tránh mass assignment vulnerability.
Dependency injection tự động cung cấp các dependency cần thiết cho class. Thay vì new UserRepository() bên trong controller, type-hint trong method: public function index(UserRepository $repo) { return $repo->all(); }. Service container của Laravel tự động khởi tạo và inject class.
Lợi ích: dễ test hơn (inject mock repository), coupling lỏng lẻo (đổi implementation mà không sửa controller), code gọn hơn. Laravel xử lý injection tự động cho route controller, middleware, commands. Giúp code linh hoạt và dễ test mà không cần khởi tạo thủ công.
Service Provider bootstrap các dịch vụ của ứng dụng. Có hai method chính: register() (bind vào container) và boot() (truy cập các service đã bind).
Ví dụ: AppServiceProvider đăng ký custom service, MailServiceProvider cài đặt mail. Định nghĩa binding: $this->app->bind(PaymentInterface::class, StripePayment::class). Dùng cho: đăng ký event listener, publish config file, mở rộng tính năng. Provider chạy sớm trong lifecycle của Laravel, lý tưởng cho các tác vụ thiết lập. Tạo custom provider bằng php artisan make:provider CustomServiceProvider. Laravel 11+: mảng providers trong config/app.php đã bị xóa — package discovery tự động, custom provider đăng ký qua AppServiceProvider hoặc bootstrap/providers.php.
Validate dữ liệu đầu vào với rules trong controller: $request->validate(["email" => "required|email", "name" => "required|string|max:100"]).
- Các rule phổ biến:
required(bắt buộc),email(email hợp lệ),unique:table(chưa có trong DB),min:5|max:20(độ dài),confirmed(khớp với field_confirmation),regex:/pattern/(khớp regex). - Hiển thị lỗi trong view:
@if($errors->any()) @foreach($errors->all() as $error) {{ $error }} @endforeach @endif. - Validation bảo vệ khỏi lưu dữ liệu xấu, cải thiện UX với thông báo lỗi, và ngăn chặn vấn đề bảo mật.
Eloquent là lớp trừu tượng database của Laravel cung cấp giao diện hướng đối tượng để thao tác database. Thay vì SQL thuần SELECT * FROM users WHERE id=1, dùng User::find(1).
Lợi ích: không phụ thuộc vào database cụ thể (dễ chuyển đổi), tự động phòng chống SQL injection, code dễ đọc và bảo trì, relationships được tích hợp sẵn, tính năng tối ưu hóa query. Mỗi bảng có class Model tương ứng với các property khớp cột. Các method như where(), orWhere(), orderBy() có thể chain: User::where("age", ">", 18)->orderBy("name")->get(). Giảm code, tăng bảo mật, dễ test.
Model đại diện cho bảng database theo cách hướng đối tượng. Tạo bằng php artisan make:model User. Các property: protected $table (override tên bảng), protected $fillable (cột được mass-assign như name, email), protected $hidden (loại khỏi output như password), protected $casts (ép kiểu như created_at thành date).
Ví dụ: $user = User::create(["name" => "John", "email" => "john@example.com"]); tạo bản ghi. Mass assignment yêu cầu mảng $fillable để bảo mật—ngăn gán các trường nhạy cảm. Model kết nối cấu trúc database với code PHP.
Relationships định nghĩa mối liên kết giữa các model. One-to-Many: User có nhiều Post. Định nghĩa trong User model: public function posts() { return $this->hasMany(Post::class); }. Truy cập: $user->posts. Many-to-One (nghịch đảo): Post belongs to User. One-to-One: User có một Profile. Many-to-Many: Post có nhiều Tag.
Ví dụ: $post->tags()->attach($tagId) tạo liên kết. Polymorphic: nhiều model cùng liên kết đến một model (như Comment trên cả Post và Video). Relationships cho phép query dữ liệu trực quan: $user->posts()->where("published", true)->get() thay vì SQL join phức tạp.
Vấn đề N+1 xảy ra khi lấy records cha rồi truy cập relationship trên từng cái.
Ví dụ: $users = User::all(); (1 query), sau đó foreach($users as $user) { echo $user->posts; } (N query thêm). Kết quả: 1+N query tổng cộng rất kém hiệu quả. Khắc phục bằng eager loading: User::with("posts")->get() tải tất cả user và post chỉ trong 2 query. Chain: User::with("posts.comments")->get(). Dùng load() để lazy eager loading: $users->load("posts"). Kiểm tra bằng debugbar để xác nhận số lượng query. Eager loading rất quan trọng cho hiệu suất.
Scope là các ràng buộc query có thể tái sử dụng. Local scope trong model: public function scopeActive($query) { return $query->where("active", true); } rồi dùng User::active()->get(). Global scope áp dụng tự động, implement GlobalScope: hữu ích cho soft delete. Scope giảm trùng lặp và tăng khả năng đọc.
Ví dụ: thay vì viết User::where("active", true)->where("age", ">", 18)->get() ở nhiều nơi, tạo scopeAdults() và scopeActive() rồi chain User::active()->adults()->get(). Scope giữ query DRY và đóng gói business logic trong model.
Accessor biến đổi dữ liệu khi đọc, mutator biến đổi khi ghi. Định nghĩa accessor: protected function name(): Attribute { return Attribute::make(get: fn($value) => ucfirst($value)); } tự động viết hoa chữ cái đầu khi truy cập. Mutator: protected function email(): Attribute { return Attribute::make(set: fn($value) => strtolower($value)); } chuyển sang chữ thường khi lưu.
Ví dụ: $user->email = "JOHN@EXAMPLE.COM" lưu thành chữ thường, echo $user->name hiển thị viết hoa dù lưu là chữ thường. Accessor/mutator tập trung logic định dạng vào một chỗ.
Soft delete đánh dấu record là đã xóa mà không thực sự xóa khỏi database. Thêm vào model: use SoftDeletes; và migration thêm $table->softDeletes(); tạo cột deleted_at. Query tự động loại trừ record đã soft-delete: User::all() không bao gồm đã xóa. Truy cập bằng: User::withTrashed()->get() (bao gồm đã xóa), User::onlyTrashed()->get() (chỉ đã xóa), $user->restore() (khôi phục), $user->forceDelete() (xóa vĩnh viễn).
Lợi ích: giữ dữ liệu để audit/phục hồi, hoàn tác xóa nhầm, tuân thủ quy định giữ bản ghi. Soft delete tăng độ an toàn dữ liệu.
Factory tạo dữ liệu giả để test: php artisan make:factory UserFactory.
- Định nghĩa:
public function definition() { return ["name" => $this->faker->name, "email" => $this->faker->unique()->safeEmail]; }rồi dùngUser::factory()->create()hoặcUser::factory(10)->create()cho 10 bản ghi. - Seeder populate database:
php artisan make:seeder UserSeederrồi gọi factoryUser::factory(100)->create()và chạy bằngphp artisan db:seed. - Thiết yếu cho development (dữ liệu giả) và testing (dữ liệu nhất quán).
- Factory dùng thư viện Faker để tạo dữ liệu ngẫu nhiên thực tế.
Query builder là giao diện fluent để xây dựng query mà không cần SQL thuần.
Ví dụ: DB::table("users")->where("age", ">", 18)->orderBy("name")->get();.
Ưu điểm: không phụ thuộc database (dễ chuyển đổi), tự động phòng SQL injection (tham số được escape), cú pháp chain dễ đọc, hỗ trợ IDE autocomplete. Các method: select(), where(), orWhere(), join(), groupBy(), having(), orderBy(), limit(), insert(), update(), delete(). So với SQL thuần DB::raw(...), query builder an toàn và dễ bảo trì hơn. Query builder là nền tảng của Eloquent.
Reverb là WebSocket server first-party của Laravel, ra mắt cùng Laravel 11 (2024) và hỗ trợ từ Laravel 10+ để broadcasting sự kiện real-time. Khác với Pusher (dịch vụ bên thứ ba tính phí): Reverb tự host (self-hosted), mã nguồn mở, miễn phí, và dùng cùng Broadcasting facade API nên có thể chuyển đổi mà không cần sửa code. Cấu hình trong config/reverb.php. Frontend vẫn dùng Laravel Echo như bình thường.
Ưu điểm: không phụ thuộc external service, giảm chi phí, scale linh hoạt. Phù hợp cho: thông báo real-time, live dashboard, tính năng cộng tác, chat.
Pennant là package feature flag chính thức của Laravel (cài riêng: composer require laravel/pennant, có official support từ Laravel 10+) để kiểm soát khả năng hiển thị tính năng. Hỗ trợ flag đơn giản và logic phức tạp theo class.
Ví dụ: Feature::define('new-checkout', fn() => rand(1,100) <= 50) cho A/B testing, hoặc Feature::define(PurchaseButton::class, fn($user) => $user->isPremium()) cho feature theo user. Dùng trong Blade: @feature('flag-name'), trong controller: Feature::active('flag-name'). Cho phép: deploy không downtime, rollout từng bước, thử nghiệm A/B, tắt/bật tính năng mà không cần deploy lại.
Pest là testing framework hiện đại được xây dựng trên PHPUnit, dùng cú pháp fluent và expect() assertion thay vì $this->assert* cồng kềnh.
Lợi ích: code test gọn sạch hơn, parallel testing mặc định, watch mode và profiling tích hợp, hỗ trợ architecture testing và snapshot testing, docs đẹp. Ví dụ Pest: test('user có thể đăng nhập', function () { expect(true)->toBeTrue(); }). Laravel docs chính thức khuyến nghị Pest mặc định. Không phải thay thế hoàn toàn PHPUnit—Pest chạy trên PHPUnit, chỉ là layer API đẹp hơn. Vẫn tương thích 100% với PHPUnit test cũ.
Cả hai đều xác thực Laravel API nhưng phục vụ nhu cầu khác nhau.
- Sanctum: nhẹ, phù hợp cho SPA cùng domain và personal access token, dùng session cho SPA và token DB-less cho mobile/external app.
- Passport: triển khai đầy đủ OAuth 2.0, phù hợp cho ứng dụng bên thứ ba cần tích hợp (như OAuth của GitHub), nặng hơn nhưng linh hoạt cho B2B.
- Quy tắc đơn giản: Sanctum cho frontend của chính bạn (SPA, mobile app công ty), Passport khi bên khác cần tích hợp vào hệ thống.
- Từ Laravel 11+, Sanctum là default được khuyến nghị cho hầu hết trường hợp.
API Resources chuyển đổi Eloquent model thành JSON response nhất quán mà không lộ schema DB.
Ví dụ: return UserResource::collection($users) thay vì return $users->toJson().
Lợi ích: tự ẩn các field nhạy cảm (password, internal ID), transform format dữ liệu (snake_case sang camelCase), include relationship có điều kiện với ->when(), tạo API contract ổn định cho frontend, version response độc lập với DB schema. Ngăn vô tình expose password hash, soft-deleted data. Tạo bằng: php artisan make:resource UserResource. Là best practice bắt buộc với bất kỳ API public nào.
Feature tests kiểm tra toàn bộ chu trình request/response bao gồm route, middleware, authentication, validation và database—bắt bug thực tế người dùng gặp.
- Unit tests cô lập từng component (Service, Model method) mà không có HTTP layer.
Ví dụ feature test: kiểm tra flow đăng nhập end-to-end với DB thực.
Ví dụ unit test: kiểm tra logic hash password trong isolation.
- Community Laravel thường ưu tiên feature test vì mang lại ROI cao hơn cho Laravel app thông thường, nhưng tỷ lệ tối ưu tùy thuộc vào từng dự án.
- Unit test phù hợp cho business logic phức tạp (tính giá, thuật toán).
- Pest nhấn mạnh feature test là chiến lược test chính.
Service Container là IoC (Inversion of Control) container quản lý các dependency của class. Thay vì tạo dependency thủ công, đăng ký một lần: app()->bind(UserRepository::class, MySQLUserRepository::class). Sau đó inject ở bất kỳ đâu: public function __construct(UserRepository $repo). Container tự động khởi tạo class đúng.
Lợi ích: một điểm để thay đổi implementation (swap repository dễ dàng), cấu hình tập trung, cho phép test với mock, lazy loading service. Truy cập trực tiếp: app()->make(UserRepository::class) hoặc dùng facade. Service Container là lõi của Laravel cho phép dependency injection toàn bộ ứng dụng.
Event cho phép giao tiếp loosely coupled—khi điều gì đó xảy ra (event UserCreated), các listener phản ứng.
- Tạo event:
php artisan make:event UserCreatedvới propertypublic $user. - Tạo listener:
php artisan make:listener SendWelcomeEmail --event=UserCreated. - Dispatch từ model:
UserCreated::dispatch($user). - Listener thực thi đồng bộ theo mặc định, hoặc queue với
implements ShouldQueue. - Event tách biệt code—logic tạo user không biết về email, notification. Laravel 11+:
EventServiceProviderđã bị xóa—listener đăng ký trongAppServiceProviderquaEvent::listen()hoặc dùng auto-discovery (event discovery tự động).
Queue trì hoãn các tác vụ tốn thời gian sang background worker. Thay vì gửi email trong request (làm chậm user), queue job: Mail::queue(new SendEmail($user)) trả về ngay. Worker xử lý các queued job bất đồng bộ. Tạo job: php artisan make:job ProcessPayment với method handle(). Cấu hình trong .env với QUEUE_CONNECTION=redis (từ Laravel 7+; không phải QUEUE_DRIVER cũ). Chạy worker: php artisan queue:work.
Lợi ích: response nhanh hơn, xử lý traffic spike, retry job thất bại tự động, xử lý theo thứ tự. Thiết yếu cho: gửi email, xử lý ảnh, tạo báo cáo, gọi API. Queue cải thiện UX và độ tin cậy hệ thống.
Middleware lọc các HTTP request/response. Tạo: php artisan make:middleware CheckAge với handle($request, $next) trả về $next($request). Laravel 11+: không còn app/Http/Kernel.php — đăng ký middleware global qua ->withMiddleware() trong bootstrap/app.php; $routeMiddleware cũng đã bị xóa.
Ví dụ: Route::get("/admin", function() {...})->middleware("admin") kiểm tra quyền admin. Middleware phổ biến: authentication (kiểm tra đăng nhập), CORS (cross-origin request), CSRF (ngăn tấn công). Middleware chain: handle() chạy trước controller, $next() tiếp tục đến middleware/controller tiếp theo, response đi ngược lại.
Broadcasting gửi dữ liệu thời gian thực đến client kết nối qua WebSocket.
- Tạo channel:
php artisan make:channel OrderChannelxác định ai có thể lắng nghe. - Broadcast event trong controller:
broadcast(new OrderShipped($order)). - Frontend dùng Laravel Echo đăng ký:
Echo.channel("order." + orderId).listen("OrderShipped", (e) => { ... }). - Use case: thông báo (tin nhắn mới xuất hiện ngay), presence channel (xem ai đang online), collaborative editing, live dashboard.
- Yêu cầu server hỗ trợ WebSocket (Pusher, Ably, hoặc self-hosted Soketi).
- Broadcasting tạo ra trải nghiệm real-time thay vì polling lãng phí tài nguyên.
Policy tập trung hóa logic phân quyền. Tạo: php artisan make:policy PostPolicy --model=Post định nghĩa các method như view(), create(), update(), delete().
Ví dụ: public function update(User $user, Post $post) { return $user->id === $post->user_id; }. Dùng trong controller: $this->authorize("update", $post); hoặc inline if (auth()->user()->can("update", $post)).
Lợi ích: quy tắc auth tập trung, tái sử dụng qua nhiều controller, dễ test, dễ đọc. Laravel 11+: AuthServiceProvider đã bị xóa — đăng ký policy bằng Gate::policy() trong AppServiceProvider hoặc để auto-discovery tự động tìm.
Laravel cung cấp công cụ testing: Unit test kiểm tra logic của một class đơn lẻ, Feature test kiểm tra chức năng end-to-end. Ví dụ feature test: $this->post("/login", ["email" => "...", "password" => "..."])->assertRedirect("/dashboard");. Dùng assertion: $this->assertEquals(), $this->assertDatabaseHas(), $this->assertStatus(200). Mocking: $this->mock(UserRepository::class, function($mock) { ... });.
Lợi ích: phát hiện bug sớm, refactor an toàn, document hành vi mong muốn, ngăn regression. Tạo test: php artisan make:test UserTest --unit (unit) hoặc không có --unit (feature). Laravel 11+ khuyến nghị Pest là testing framework mặc định với cú pháp fluent và parallel testing, thay thế cho PHPUnit trực tiếp.
Facade cung cấp giao diện giống static đến các service trong container. Auth::user() gọi authentication service bên dưới theo kiểu static. Các facade khác: DB::table(), Cache::get(), Mail::send(). Bên dưới: facade Auth resolve thành \Illuminate\Auth\AuthManager từ container.
Ưu điểm: cú pháp static tiện lợi, vẫn có thể inject dependency, ý định rõ ràng, dễ mock trong test. Thay vì inject AuthManager khắp nơi, dùng Auth::user(). Tạo custom facade: extend class Facade và định nghĩa getFacadeAccessor() trả về key trong container. Facade cân bằng sự tiện lợi với lợi ích của dependency injection.
Collection cung cấp các method mạnh mẽ để làm việc với mảng dữ liệu. Eloquent query trả về collection: $users = User::all(); rồi $users->map(fn($u) => $u->email)->unique()->sort(). Các method quan trọng: map() (biến đổi), filter() (lọc), each() (lặp), pluck() (lấy cột), groupBy() (nhóm), chunk() (chia nhỏ), diff() (so sánh), merge() (gộp).
Ví dụ: User::all()->where("active", true)->pluck("email")->all() lấy email user đang hoạt động. Lưu ý: Collection->where() hoạt động in-memory (filter sau khi load toàn bộ), khác với query builder User::where("active", true)->pluck("email")->all() filter ở DB. Với dataset lớn, luôn ưu tiên query builder để tránh load cả bảng vào bộ nhớ.
DTO là các value object đơn giản đóng gói dữ liệu request/response không có business logic, đảm bảo type safety.
Ví dụ: class CreateUserDTO { public function __construct(public string $name, public string $email, public int $age) {} }.
Lợi ích: type hinting rõ ràng thay vì unpack array mù quáng, bắt lỗi type tại compile time, self-document tham số mong muốn, IDE autocomplete đầy đủ, dễ refactor qua nhiều controller/service. Phân biệt với Eloquent model (entity DB có ORM logic). Với PHP 8.2+ readonly class, DTO trở nên bất biến và an toàn hơn: readonly class CreateUserDTO { ... }.
Architecture testing kiểm tra quy tắc cấu trúc code mà không cần thực thi logic, phát hiện vi phạm design sớm. Ví dụ với Pest: arch('Service không được truy cập trực tiếp DB')->expect('App\\Services')->not->toUseClasses(['Illuminate\\Database\\Eloquent\\Model']).
Lợi ích: ngăn tight coupling, bắt dependency injection bị bỏ qua, phát hiện cross-module dependency trái phép, enforce naming convention. Dùng cho: đảm bảo model nằm trong Models/, service trong Services/, controller chỉ gọi service. Vi phạm bị bắt tại CI thay vì runtime—tiết kiệm debug thời gian thực.
Livewire 3 là framework Laravel để xây dựng component full-stack reactive bằng PHP thuần—không cần JavaScript. State phía server đồng bộ với frontend qua AJAX request tối ưu, loại bỏ việc quản lý API contract.
Ví dụ: form validation, live search, cập nhật giỏ hàng đều xử lý bằng PHP.
Ưu điểm: ít JavaScript hơn, tái sử dụng Laravel validation trong UI, tận dụng Laravel tooling.
Nhược điểm: thêm latency so với client-side (tốt cho tần suất thấp, không phù hợp tần suất cao), tải server lớn hơn. Dùng cho: admin panel, dashboard, CRUD interface. Không phù hợp: game real-time, cập nhật tần suất rất cao. Ngày càng phổ biến như alternative cho SPA.