Phỏng vấn vị trí lập trình PHP / Laravel


Chào bạn! Một danh sách 50 câu hỏi kèm code demo là một tài liệu ôn tập khá đồ sộ đấy. Để đảm bảo chất lượng và độ chi tiết tốt nhất, mình sẽ chia lộ trình này thành các nhóm chủ đề cốt lõi.

Dưới đây là Phần 1: 10 câu hỏi quan trọng về PHP Core và Laravel Fundamentals. Nếu bạn thấy phong cách này ổn, mình sẽ tiếp tục các phần tiếp theo cho đến khi đủ 50 câu nhé!


  • Lời giải: Cả hai đều dùng để chèn file. Tuy nhiên, nếu file không tồn tại:

    • include: Đưa ra cảnh báo (Warning) và tiếp tục thực thi script.

    • require: Đưa ra lỗi nghiêm trọng (Fatal Error) và dừng chương trình ngay lập tức.

  • Code Demo:

PHP
// include 'non_existent_file.php'; 
// echo "Vẫn chạy tiếp được!";

// require 'non_existent_file.php'; 
// echo "Dòng này sẽ không bao giờ được in ra.";
  • Lời giải: PSR (PHP Standard Recommendations) là các tiêu chuẩn viết code do nhóm PHP-FIG đề ra. Laravel tuân thủ chặt chẽ PSR-4 (Autoloading) và PSR-12 (Coding Style). Việc này giúp code đồng nhất, dễ bảo trì và tương thích giữa các thư viện khác nhau.

  • Lời giải: Trait là cơ chế giúp tái sử dụng code trong các ngôn ngữ đơn kế thừa như PHP. Nó cho phép một class sử dụng các phương thức từ nhiều nguồn khác nhau mà không cần kế thừa từ nhiều cha.

  • Code Demo:

PHP
trait Shareable {
    public function share($platform) {
        return "Sharing to $platform";
    }
}

class Post {
    use Shareable;
}

$post = new Post();
echo $post->share('Facebook');

  • Lời giải: Đây là "trái tim" của Laravel. Nó là một công cụ mạnh mẽ để quản lý các class dependencies và thực hiện Dependency Injection. Bạn đăng ký một "hợp đồng" (interface) và Container sẽ quyết định class cụ thể nào sẽ được khởi tạo.

  • Lời giải: Middleware đóng vai trò như một lớp lọc (filter) cho các request HTTP đi vào ứng dụng. Nó thường được dùng để kiểm tra xác thực (Auth), phân quyền, hoặc log dữ liệu trước khi request đến được Controller.

  • Code Demo:

PHP
public function handle(Request $request, Closure $next) {
    if ($request->age <= 18) {
        return redirect('home');
    }
    return $next($request);
}
  • Lời giải: Laravel tự động "tiêm" các object cần thiết vào constructor hoặc method của Controller thông qua Type-hinting nhờ vào Service Container.

  • Code Demo:

PHP
class UserController extends Controller {
    protected $users;

    // Laravel tự hiểu và tạo instance của UserRepository
    public function __construct(UserRepository $users) {
        $this->users = $users;
    }
}
  • Lời giải: * Lazy Loading: Chỉ load dữ liệu quan hệ khi được gọi đến (gây ra lỗi N+1 query).

    • Eager Loading: Load sẵn các quan hệ ngay từ đầu bằng phương thức with().

  • Code Demo:

PHP
// Eager Loading (Tối ưu: chỉ 2 query)
$books = Book::with('author')->get();

// Lazy Loading (Tệ: 1 query lấy sách + N query lấy tác giả)
$books = Book::all();
foreach ($books as $book) {
    echo $book->author->name; 
}
  • Lời giải: Query Scope giúp bạn định nghĩa các logic truy vấn chung trong Model để có thể tái sử dụng dễ dàng.

  • Code Demo:

PHP
// Trong Model
public function scopeActive($query) {
    return $query->where('status', 'active');
}

// Cách dùng
$users = User::active()->get();
  • Lời giải: Laravel tạo ra một "token" ngẫu nhiên cho mỗi session. Khi gửi dữ liệu qua POST/PUT, Laravel sẽ so khớp token từ form gửi lên với token trong session. Nếu không khớp, request sẽ bị từ chối (419 error).

  • Code Demo:

HTML
<form method="POST" action="/profile">
    @csrf
    </form>
  • Lời giải: * Accessor: Chỉnh sửa dữ liệu sau khi lấy từ DB ra (ví dụ: viết hoa tên).

    • Mutator: Chỉnh sửa dữ liệu trước khi lưu vào DB (ví dụ: hash mật khẩu).

  • Code Demo:

PHP
// Accessor
protected function firstName(): Attribute {
    return Attribute::make(
        get: fn (string $value) => ucfirst($value),
    );
}

// Mutator
protected function password(): Attribute {
    return Attribute::make(
        set: fn (string $value) => bcrypt($value),
    );
}
  • Lời giải: * find($id): Tìm một bản ghi theo Primary Key (thường là ID). Trả về 1 Model hoặc null.

    • first(): Trả về bản ghi đầu tiên khớp với điều kiện query. Trả về 1 Model hoặc null.

    • get(): Trả về một Collection chứa tất cả bản ghi khớp điều kiện.

  • Code Demo:

PHP
$user = User::find(1); 
$firstAdmin = User::where('role', 'admin')->first();
$allAdmins = User::where('role', 'admin')->get();
  • Lời giải: Thay vì xóa vĩnh viễn khỏi DB, Laravel thêm cột deleted_at. Dữ liệu vẫn còn đó nhưng mặc định sẽ bị ẩn khỏi các câu query.

  • Code Demo:

PHP
// Trong Model: use SoftDeletes;
$user->delete(); // Đánh dấu xóa

// Khôi phục
User::withTrashed()->where('id', 1)->restore();
  • Lời giải: Đảm bảo một nhóm các câu lệnh SQL hoặc là thành công hết, hoặc là thất bại hết (Atomicity). Tránh việc dữ liệu bị "nửa vời" (ví dụ: trừ tiền tài khoản A nhưng chưa cộng tiền tài khoản B).

  • Code Demo:

PHP
DB::transaction(function () {
    DB::table('users')->update(['votes' => 1]);
    DB::table('posts')->delete();
});
  • Lời giải: * attach(): Thêm một bản ghi vào bảng trung gian (có thể gây trùng lặp).

    • detach(): Xóa bản ghi khỏi bảng trung gian.

    • sync(): "Làm sạch" bảng trung gian và chỉ giữ lại các ID được truyền vào (Rất hữu ích cho tính năng cập nhật Tags/Categories).

  • Code Demo:

PHP
$user->roles()->attach(1); // Thêm role 1
$user->roles()->sync([1, 2, 3]); // Xóa hết role cũ, chỉ giữ lại 1, 2, 3

  • Lời giải: Là các class riêng biệt chứa logic validate, giúp Controller gọn gàng hơn (tuân thủ Single Responsibility Principle).

  • Code Demo:

PHP
// Tạo bằng: php artisan make:request StorePostRequest
public function rules() {
    return [
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ];
}
  • Lời giải: * Authentication (Xác thực): Kiểm tra xem bạn là ai (Login).

    • Authorization (Phân quyền): Kiểm tra xem bạn có quyền làm gì (Gates & Policies).

  • Code Demo (Authorization):

PHP
if (Gate::allows('update-post', $post)) {
    // Chỉ chủ bài viết mới được sửa
}
  • Lời giải: Giới hạn số lượng request một user/IP có thể gửi trong một khoảng thời gian để tránh tấn công DoS hoặc spam.

  • Code Demo (Route):

PHP
Route::middleware('throttle:60,1')->group(function () {
    Route::get('/user', function () { /* ... */ });
}); // Tối đa 60 requests mỗi phút

  • Lời giải: Dùng để nhóm các "Event Listeners" cho một Model. Bạn có thể lắng nghe các sự kiện như creating, updated, deleted của một Model cụ thể.

  • Code Demo:

PHP
class UserObserver {
    public function created(User $user) {
        // Gửi mail welcome ngay khi user vừa đăng ký xong
        Mail::to($user)->send(new WelcomeMail());
    }
}
  • Lời giải: Là lớp trung gian giữa Controller và Model. Nó giúp tách biệt logic truy vấn DB khỏi Controller, giúp code dễ Unit Test và dễ thay đổi DB engine sau này.

  • Code Demo:

PHP
interface UserRepositoryInterface {
    public function all();
}

class SqlUserRepository implements UserRepositoryInterface {
    public function all() { return User::all(); }
}
  • Lời giải: Đưa các tác vụ nặng (gửi email, xử lý ảnh) vào hàng đợi để xử lý sau (background), giúp phản hồi request của người dùng ngay lập tức mà không phải chờ.

  • Code Demo:

PHP
// Dispatch một job
ProcessPodcast::dispatch($podcast);

  • Lời giải: * Closure: Cần dùng từ khóa use để truy cập biến bên ngoài.

    • Arrow function (PHP 7.4+): Tự động bắt biến từ scope cha (short syntax).

  • Code Demo:

PHP
$y = 1;
$fn1 = fn($x) => $x + $y; // Tự hiểu $y
$fn2 = function($x) use ($y) { return $x + $y; };
  • Lời giải: Static method thuộc về class (gọi qua Class::method()), không cần khởi tạo object. Non-static thuộc về instance (đối tượng cụ thể), gọi qua $this.

  • Lời giải: self tham chiếu đến class nơi nó được định nghĩa, còn static tham chiếu đến class thực tế đang được gọi (hữu ích trong kế thừa).

  • Lời giải: * Interface: Chỉ định nghĩa "hành động" (methods), không có code thực thi. Một class có thể implements nhiều interface.

    • Abstract Class: Có thể chứa cả method rỗng và method có code. Một class chỉ kế thừa được một abstract class.

  • Lời giải: md5sha1 chạy cực nhanh nên dễ bị tấn công Brute-force. password_hash() sử dụng thuật toán mạnh (như BCrypt) và tự động thêm "salt" ngẫu nhiên.

Tiếp tục với lộ trình, chúng ta sẽ đi vào các phần "nâng cao" thực sự, bao gồm Testing, Performance Optimization, Laravel 11 Updates và các kỹ thuật xử lý hệ thống lớn.


  • Lời giải: * Unit Test: Kiểm tra một hàm hoặc một class cô lập (không chạm vào DB, Network). Rất nhanh.

    • Feature Test: Kiểm tra một tính năng hoàn chỉnh (ví dụ: một API endpoint). Nó chạy qua Route, Controller, Middleware và DB.

  • Code Demo (Pest PHP):

PHP
// Unit Test
test('sum function adds numbers', function () {
    expect(sum(1, 2))->toBe(3);
});

// Feature Test
test('user can login', function () {
    $response = $this->post('/login', ['email' => 'a@b.com', 'password' => '123']);
    $response->assertStatus(302);
});
  • Lời giải: Là việc tạo ra một "đối tượng giả" để thay thế cho một dịch vụ thật (như gửi SMS, thanh toán Stripe) khi chạy Test, giúp test không phụ thuộc vào bên thứ 3 và chạy nhanh hơn.

  • Code Demo:

PHP
public function test_payment_is_called() {
    $mock = Mockery::mock(PaymentGateway::class);
    $mock->shouldReceive('charge')->once()->andReturn(true);
    
    $this->instance(PaymentGateway::class, $mock);
}
  • Lời giải: PHPUnit là tiêu chuẩn lâu đời dùng Class-based. Pest là một "vỏ bọc" hiện đại dựa trên PHPUnit nhưng dùng cú pháp functional, giúp code test ngắn gọn và dễ đọc hơn (Laravel hiện mặc định khuyến khích dùng Pest).


  • Lời giải: Bạn nên đánh Index cho các cột thường xuyên xuất hiện trong mệnh đề WHERE, ORDER BY, hoặc các cột dùng để JOIN. Tuy nhiên, quá nhiều Index sẽ làm chậm lệnh INSERT/UPDATE.

  • Code Demo (Migration):

PHP
Schema::table('users', function (Blueprint $table) {
    $table->index('email'); // Đánh index cho cột email
});
  • Lời giải: Giúp lưu trữ các kết quả tính toán hoặc truy vấn nặng vào bộ nhớ nhanh (Redis, Memcached) để tái sử dụng, thay vì phải chạy lại logic đó.

  • Code Demo:

PHP
$users = Cache::remember('active_users', 3600, function () {
    return User::where('active', 1)->get();
});
  • Lời giải: Redis là một In-memory data store. Trong Laravel, nó thường dùng cho:

    1. Cache dữ liệu.

    2. Driver cho Queue (hàng đợi).

    3. Lưu trữ Session.

    4. Xử lý Real-time (kết hợp với Socket.io).

  • Lời giải: Là lỗi khi bạn thực hiện 1 query lấy danh sách cha, sau đó với mỗi cha lại chạy thêm 1 query lấy con. Bạn có thể dùng package laravel-query-detector hoặc Laravel Telescope để phát hiện.


  • Lời giải: Là công cụ build frontend (thay thế cho Laravel Mix/Webpack). Nó cực nhanh nhờ sử dụng Native ESM trong quá trình phát triển, giúp hot-reload (cập nhật code giao diện) gần như tức thì.

  • Lời giải: Cho phép bạn tự định nghĩa cách chuyển đổi dữ liệu từ DB sang kiểu dữ liệu PHP và ngược lại.

  • Code Demo:

PHP
protected function casts(): array {
    return [
        'options' => AsArrayObject::class, // Tự động convert JSON sang Array
    ];
}
  • Lời giải: Thay vì cài đặt nhiều Cron job trên Server, bạn chỉ cần cài 1 cron gọi lệnh schedule:run. Toàn bộ lịch trình sẽ được quản lý trong code Laravel.

  • Code Demo (routes/console.php hoặc app/Console/Kernel.php):

PHP
Schedule::command('emails:send')->dailyAt('13:00');
  • Lời giải: Là một dashboard giúp giám sát hiệu năng hệ thống theo thời gian thực (CPU, Memory, các Query chậm, các Job bị lỗi).

  • Lời giải: Dùng để tự động xóa các bản ghi cũ không còn cần thiết (ví dụ: log cũ, tin nhắn rác) một cách định kỳ.


  • Lời giải: Là kiểu tấn công chèn mã SQL vào input. Laravel sử dụng PDO Parameter Binding trong Eloquent và Query Builder, giúp các input luôn được xử lý dưới dạng tham số, không phải là một phần của câu lệnh thực thi.

  • Lời giải: Là lỗ hổng khi người dùng gửi thêm các trường không mong muốn (ví dụ: is_admin = 1) qua request. Laravel chặn điều này bằng $fillable (danh sách cột được phép) hoặc $guarded.

  • Code Demo:

PHP
protected $fillable = ['title', 'content']; // Chỉ 2 trường này được update hàng loạt
  • Lời giải: Cách kết nối bảo mật đến server. Trong Laravel, ta thường dùng Laravel Forge hoặc Envoy để tự động hóa quá trình deploy qua SSH.


  • Lời giải: Các module cấp cao không nên phụ thuộc vào module cấp thấp, cả hai nên phụ thuộc vào Abstraction (Interface).

  • Ví dụ: Controller không nên gọi trực tiếp class SmsZalo, mà nên gọi qua SmsServiceInterface.

  • Lời giải: Cách viết tắt để khai báo và gán giá trị cho property ngay trong constructor.

  • Code Demo:

PHP
// Cũ
public string $name;
public function __construct(string $name) { $this->name = $name; }

// Mới (PHP 8)
public function __construct(public string $name) {}
  • Lời giải: * Union (string|int): Chấp nhận một trong các kiểu.

    • Intersection (TypeA & TypeB): Phải thỏa mãn đồng thời cả hai kiểu (thường dùng với Interface).

  • Lời giải: Nó biên dịch các phần code PHP sang mã máy trực tiếp thay vì qua Zend VM, giúp tăng tốc đáng kể các tác vụ tính toán nặng (nhưng ít tác dụng với web thuần I/O).

  • Lời giải: Là nơi trung tâm để cấu hình ứng dụng. Bạn dùng nó để bind các class vào Service Container hoặc đăng ký các event, middleware.

  • Lời giải: Kỹ thuật gửi sự kiện từ Server đến Client qua WebSockets để làm các tính năng Real-time như Chat, Thông báo mà không cần F5 trang.

  • Lời giải: Collection là một wrapper mạnh mẽ của Laravel cho mảng. map() là một method trong đó để biến đổi dữ liệu.

  • Lời giải: Cho phép một Model thuộc về nhiều Model khác chỉ bằng một mối quan hệ duy nhất (Ví dụ: Model Comment có thể thuộc về cả PostVideo).

  • Lời giải: Một giao diện dashboard và hệ thống cấu hình cho Redis Queues, giúp theo dõi số lượng Job, thời gian xử lý và các Job thất bại.

  • Lời giải: Để đơn giản hóa cấu trúc thư mục (Slim Skeleton). Giờ đây việc đăng ký Middleware và Provider được thực hiện trực tiếp trong file bootstrap/app.php.

Phản hồi từ học viên

5

Tổng 0 đánh giá
Developer Toolbox

TEXT CASE

FORMAT & CLEAN

ENCODE & DECODE

JSON & CRYPTO

Đã sao chép!!!
Gozic - Hệ thống học lập trình, luyện thi, kiểm tra trắc nghiệm trực tuyến uy tín tại Việt Nam.
Hotline: 0967025996
Gozic - Hệ thống học lập trình, luyện thi, kiểm tra trắc nghiệm trực tuyến uy tín tại Việt Nam.