Blog về kiểm thử ·

Lý thuyết kiểm thử khi phỏng vấn: tư duy giải quyết vấn đề cho QA và lập trình viên

Biết định nghĩa kiểm thử hồi quy là hữu ích. Giải thích cần kiểm tra gì sau khi thay đổi chức năng chuyển đổi khách hàng tiềm năng, ở cấp độ nào, còn hữu ích hơn. Kết nối lý thuyết với điều kiện rõ ràng, quan sát và quyết định có thể bảo vệ trong buổi phỏng vấn.

Đây là tài liệu học tập, không phải bộ câu hỏi nội bộ của nhà tuyển dụng hay cam kết có việc làm. Câu hỏi và tình huống nghiệp vụ do ban biên tập xây dựng; các quy tắc này không cam kết hành vi hiện tại của mô-đun trong trình mô phỏng. Phần dành cho lập trình viên tập trung vào kiểm thử, không thay thế việc học thuật toán, ngôn ngữ hoặc thiết kế hệ thống. Thuật ngữ cơ bản được đối chiếu với ISTQB CTFL 4.0.1; tác giả và chủ sở hữu bản quyền được ghi trong tài liệu ISTQB liên kết. Đây là nội dung độc lập, không phải khóa học được công nhận chính thức.

Bốn bước để trả lời có căn cứ
  1. Làm rõ quy tắc và rủi ro
  2. Chọn dữ liệu và hành động
  3. Nêu kết quả mong đợi
  4. Giải thích giới hạn của phép kiểm tra

1. Kiểm thử, QA và bằng chứng về chất lượng

Kiểm thử cung cấp thông tin về sản phẩm và rủi ro, không phải chứng nhận rằng sản phẩm không có lỗi. QA rộng hơn việc kiểm tra chức năng đã hoàn thành: đội có thể cải thiện cách rà soát yêu cầu, chuẩn bị dữ liệu và phản hồi ngay từ đầu. Gỡ lỗi tìm nguyên nhân của vấn đề quan sát được và sửa nó. Một người có thể làm các hoạt động này, nhưng mục tiêu của chúng vẫn khác nhau.

Hãy tưởng tượng CRM: nhân viên bấm chuyển đổi lead và một khách hàng xuất hiện. Đó là quan sát, chưa phải kết luận đúng. Yêu cầu nói mỗi lead tạo tối đa một khách hàng, thao tác lặp lại trả về khách hàng đã có. Test oracle, tức căn cứ để đánh giá kết quả, không phải thông báo màu xanh mà là số khách hàng và liên kết với lead ban đầu. Phép kiểm tra phải quan sát những thuộc tính đó.

Phân biệt sai sót của con người, khiếm khuyết trong sản phẩm công việc và sự cố khi chạy. Hiểu sai về yêu cầu gửi lại có thể khiến mã thiếu cơ chế chống trùng; hai khách hàng sau lần gửi lại là sự cố quan sát được. Báo cáo không cần đoán người viết mã đã nghĩ gì: vi phạm quy tắc có thể tái hiện đã là bằng chứng hữu ích.

Câu hỏi phỏng vấn

Chuyển đổi lead đã tạo khách hàng một lần. Có thể nói chức năng đã được kiểm thử chưa?

Xem phân tích và câu hỏi tiếp theo

Mới kiểm tra một luồng thành công với dữ liệu cụ thể. Tôi ghi ID lead, ID khách hàng và kiểm tra liên kết. Sau đó xem xét riêng việc gửi lại, thiếu quyền, dữ liệu không đầy đủ và gián đoạn thao tác. Mức độ đầy đủ phụ thuộc phạm vi và rủi ro đã thống nhất; chạy được một lần không bao phủ các điều kiện đó. Báo cáo cần tách phần đã kiểm tra và giới hạn còn lại.

Người phỏng vấn hỏi thêm: Yêu cầu không nói về gửi lại. Có nên lập tức báo lỗi trùng khách hàng?

Trước hết ghi nhận hiện tượng và rủi ro, rồi làm rõ quy tắc với người phụ trách sản phẩm. Trùng dữ liệu có thể nghiêm trọng, nhưng không nên coi kỳ vọng cá nhân là yêu cầu đã thống nhất nếu chưa có căn cứ. Ràng buộc dữ liệu hoặc quyết định trước đó của đội có thể cung cấp căn cứ này.

Góc nhìn của lập trình viên

Trước khi triển khai, nêu bất biến: điều kiện luôn phải đúng. Trong ví dụ này, một lead_id liên kết tối đa một khách hàng. Rà soát mã, ràng buộc cơ sở dữ liệu và kiểm thử cùng bảo vệ một ý nghĩa nghiệp vụ, không phải ba chi tiết kỹ thuật rời rạc.

Điểm dễ nhầm: Chưa tìm thấy lỗi không có nghĩa là không tồn tại lỗi. Kết quả đạt chỉ có giá trị trong dữ liệu, môi trường và quan sát của phép kiểm tra.

Tài liệu gốc về chủ đề này

2. Yêu cầu có thể kiểm thử và tiêu chí chấp nhận

Câu “nhiệm vụ chuyển sang quá hạn đúng lúc” che giấu ít nhất ba quyết định: lưu thời hạn thế nào, dùng đồng hồ nào và bằng đúng thời hạn có tính là quá hạn không. Hợp đồng của bài tập lưu due_at theo UTC, lấy giờ máy chủ làm chuẩn và chỉ quá hạn khi now > due_at và status != done. Nhờ vậy có thể tính kết quả mong đợi trước khi chạy.

Với hạn 12:00:00 UTC, nhiệm vụ đang mở chưa quá hạn lúc 11:59:59, vẫn chưa quá hạn đúng 12:00:00, nhưng quá hạn lúc 12:00:01. Nhiệm vụ hoàn thành không quá hạn ở cả ba thời điểm. Đổi múi giờ hiển thị chỉ đổi cách biểu diễn, không đổi thời điểm. Đây là các rủi ro khác nhau, không phải ba lần bấm giống nhau.

Tiêu chí chấp nhận mô tả thuộc tính cần có của một chức năng. Điều kiện chung để đội phát hành còn có thể bao gồm rà soát, tài liệu và các phép kiểm tra. Không thay thế khái niệm này bằng khái niệm kia: “mọi bài kiểm thử đều đạt” không giải thích quy tắc nghiệp vụ về quá hạn.

Câu hỏi phỏng vấn

Bạn kiểm thử yêu cầu “tìm khách hàng nhanh” như thế nào?

Xem phân tích và câu hỏi tiếp theo

Trước hết làm rõ người dùng, lượng dữ liệu, truy vấn, tải và điểm đo thời gian. Ví dụ có thể đề xuất thống nhất p95 thời gian phản hồi máy chủ không quá 500 ms ở 50 yêu cầu mỗi giây với một triệu bản ghi, kèm giới hạn tỷ lệ lỗi. p95 nghĩa là 95% phép đo không vượt giá trị đó. Đây là mục tiêu ví dụ, không phải chuẩn chung. Tôi đo phân bố và lỗi, không chọn một yêu cầu nhanh nhất.

Người phỏng vấn hỏi thêm: Thời gian trung bình 200 ms. Vậy đã đạt yêu cầu?

Chưa chắc: trung bình có thể che khuất nhóm phản hồi rất chậm, còn yêu cầu lỗi có thể kết thúc nhanh. Cần phân vị đã thống nhất, tỷ lệ lỗi và điều kiện tải tương ứng. Lưu cấu hình tải, phiên bản dịch vụ, thời lượng và quy tắc làm nóng để tái lập kết quả.

Góc nhìn của lập trình viên

Đồng hồ có thể điều khiển và múi giờ rõ ràng giúp kiểm tra biên mà không phải chờ thời gian thật. Không tính kỳ vọng bằng chính đoạn mã đang kiểm thử: cùng một lỗi ở hai phía có thể làm phép so sánh vẫn đạt.

Điểm dễ nhầm: Mốc 500 ms tự chọn không trở thành yêu cầu đã thống nhất chỉ vì dễ tự động hóa.

Tài liệu gốc về chủ đề này

3. Cấp độ, loại kiểm thử, kiểm tra lại và hồi quy

Cấp độ nói về ranh giới đối tượng: một thành phần, các thành phần phối hợp, hệ thống hoàn chỉnh hay tương tác giữa các hệ thống. Loại kiểm thử nói về thuộc tính như chức năng hoặc hiệu năng. Kiểm thử chấp nhận xem xét sự phù hợp với nhu cầu đã thống nhất. Một phép kiểm tra có thể vừa thuộc một cấp độ vừa thuộc một loại; đây không phải hai danh sách loại trừ nhau.

Sau khi sửa lỗi chuyển đổi lead hai lần, kiểm tra xác nhận tái hiện tình huống cũ và xác nhận bản sửa. Hồi quy tìm tác động ngoài ý muốn: chuyển đổi bình thường, quyền của nhân viên và xử lý khách hàng đã tồn tại. Smoke test là kiểm tra ngắn về khả năng hoạt động của bản dựng để quyết định có nên tiếp tục kiểm tra sâu.

Một rủi ro CRM ở các ranh giới kiểm thử
Phép kiểm tra Quan sát được gì Không chứng minh được gì
Thành phầnHàm từ chối lead_id rỗngCơ sở dữ liệu thật chặn hai khách hàng
Tích hợp cơ sở dữ liệuHai yêu cầu giữ liên kết duy nhấtTrình duyệt giải thích lỗi rõ ràng
Hệ thống qua giao diệnNhân viên chuyển đổi và thấy khách hàngMọi kiểu lỗi của dịch vụ bên ngoài
Chấp nhậnLuồng đã thống nhất đáp ứng nhu cầu nhân viênKhông còn lỗi kỹ thuật nào

Câu hỏi phỏng vấn

Tại sao cần kiểm tra tích hợp khi mọi unit test đều đạt?

Xem phân tích và câu hỏi tiếp theo

Unit test có thể thay cơ sở dữ liệu bằng stub chấp nhận mọi giá trị. Cơ sở dữ liệu thật có ràng buộc, kiểu dữ liệu và giao dịch. Tôi chọn kiểm tra tích hợp cho rủi ro ở ranh giới đó, chẳng hạn ghi đồng thời. Chạy mọi tổ hợp qua trình duyệt tốn kém và khó xác định nguyên nhân hơn, nên kiểm thử đầu cuối bổ sung chứ không thay thế cấp thấp hơn.

Người phỏng vấn hỏi thêm: Có nên lặp nguyên bộ kiểm thử ở mọi cấp độ?

Không máy móc. Nhiều tổ hợp quy tắc có thể kiểm tra gần logic, hợp đồng kết nối kiểm tra riêng, còn giao diện giữ các luồng quan trọng. Lặp lại phải nhằm rủi ro mới như mất trường khi tuần tự hóa, không chỉ để tăng số bài kiểm thử.

Góc nhìn của lập trình viên

Kim tự tháp kiểm thử giúp thảo luận chi phí phản hồi, không áp đặt tỷ lệ phần trăm. Chọn cấp độ hẹp nhất có thể phát hiện lỗi mục tiêu, đồng thời giữ các kiểm tra phối hợp thành phần thật.

Điểm dễ nhầm: Tích hợp không đơn giản có nghĩa là chậm; tự động hóa không phải một cấp độ kiểm thử.

Tài liệu gốc về chủ đề này

4. Lớp tương đương, giá trị biên và tổ hợp

Quy tắc bài tập: quantity bắt buộc, là số nguyên từ 1 đến 99 gồm hai đầu; chuỗi, null và số thập phân bị từ chối mà không đổi giỏ hàng. Có lớp hợp lệ 1–99, giá trị dưới và trên khoảng, cùng các lớp sai kiểu và thiếu trường. Một giá trị không đại diện cho mọi nguyên nhân bị từ chối.

Các giá trị biên hữu ích là 0, 1, 2 và 98, 99, 100. Giá trị 50 kiểm tra trường hợp thông thường. null, bỏ trường, chuỗi "2" và số 1.5 kiểm tra những quy tắc khác của hợp đồng. Với mỗi yêu cầu bị từ chối, còn phải xác nhận giỏ hàng không đổi. Nếu hợp đồng cho phép đổi chuỗi thành số, kỳ vọng cho "2" sẽ khác.

Pairwise là bao phủ từng cặp: chọn tổ hợp để mỗi cặp giá trị của hai tham số xuất hiện ít nhất một lần. Hai trình duyệt, hai vai trò và hai ngôn ngữ có tám tổ hợp đầy đủ. Bốn dòng dưới bao phủ mọi cặp nhưng không mọi bộ ba. Nếu biết rủi ro chỉ xảy ra với viewer dùng Firefox bằng tiếng Nga, phải bổ sung đúng bộ ba đó.

Bao phủ từng cặp: bốn tổ hợp thay vì tám
Trình duyệt Vai trò Ngôn ngữ
Chromeadminen
Chromeviewerru
Firefoxadminru
Firefoxvieweren

Câu hỏi phỏng vấn

Chỉ kiểm tra quantity = 1 và quantity = 99 đã đủ chưa?

Xem phân tích và câu hỏi tiếp theo

Hai giá trị đó kiểm tra việc chấp nhận biên, chưa kiểm tra từ chối giá trị ngoài biên. Tôi bổ sung 0, 100, giá trị sát biên, sai kiểu và thiếu trường theo hợp đồng. Khi thời gian hạn chế, ưu tiên sai số lượng và thay đổi giỏ hàng âm thầm sau lỗi. Tôi nêu những kiểm tra hoãn lại thay vì tuyên bố bao phủ hoàn toàn.

Người phỏng vấn hỏi thêm: Tại sao không thử mọi số từ 1 đến 99?

Nếu quy tắc giống nhau trong khoảng, lặp lại như vậy cung cấp ít thông tin hơn kiểm tra các nguyên nhân từ chối khác nhau. Nhưng phải xem lại giả định nếu có ngưỡng giảm giá hoặc đóng gói: chúng tạo lớp và biên mới.

Góc nhìn của lập trình viên

Kiểm thử tham số hóa nên thể hiện đầu vào, kỳ vọng và ý nghĩa từng trường hợp. Một trăm dòng dữ liệu tương tự không thay thế xác nhận rằng yêu cầu bị từ chối không ghi dữ liệu.

Điểm dễ nhầm: Bao phủ từng cặp không bảo đảm phát hiện lỗi phụ thuộc ba tham số trở lên.

Tài liệu gốc về chủ đề này

5. Chuyển trạng thái: bài tập khóa đăng nhập rõ điều kiện

Quy định đầy đủ: với tài khoản tồn tại, năm lần liên tiếp nhập sai mật khẩu kích hoạt khóa 15 phút từ lần sai thứ năm, theo giờ máy chủ. Đăng nhập thành công trước khi bị khóa đặt bộ đếm về 0. Khi đang khóa, mọi mật khẩu đều bị từ chối và không kéo dài hạn khóa. Khi now >= locked_until, bỏ khóa, đặt lại bộ đếm và xử lý yêu cầu mới bình thường. Mọi thiết bị dùng chung bộ đếm của tài khoản.

Trạng thái không chỉ là khóa hay mở, mà còn gồm bộ đếm và thời gian. Đặt lại tài khoản trước từng kịch bản; nếu không, lần sai trước đó làm thay đổi ý nghĩa kiểm tra tiếp theo. Đồng hồ điều khiển được cho phép tái hiện 14:59 và 15:00 mà không chờ thật. Khi kiểm tra thủ công, ghi mốc giờ máy chủ và độ chính xác chấp nhận được.

Kỳ vọng theo hợp đồng khóa tài khoản của bài tập
Trạng thái ban đầu Hành động Kết quả
Đã sai 4 lầnMật khẩu đúngĐăng nhập được; bộ đếm 0
Đã sai 4 lầnMật khẩu saiTừ chối; bắt đầu khóa 15 phút
Đã khóa 14:59Mật khẩu đúngTừ chối; hạn khóa không đổi
Đã khóa đúng 15:00Mật khẩu đúngĐăng nhập được; bộ đếm 0
Khóa đã hết hạnMật khẩu saiTừ chối; bộ đếm mới là 1

Câu hỏi phỏng vấn

Những phép kiểm tra nào phân biệt kiểm thử khóa tài khoản với kiểm tra một thông báo lỗi?

Xem phân tích và câu hỏi tiếp theo

Tôi kiểm tra tích lũy bộ đếm, chuyển trạng thái ở lần sai thứ năm, đặt lại sau đăng nhập đúng trước khi khóa, từ chối mật khẩu đúng lúc khóa và biên mở khóa. Sau đó đổi thiết bị để xác nhận bộ đếm chung. Mỗi trường hợp ghi trạng thái đầu, hành động, kết quả và thay đổi bộ đếm hoặc hạn khóa. Một thông báo “sai mật khẩu” không đủ cho các kết luận đó.

Người phỏng vấn hỏi thêm: Sau ba lần sai, hai yêu cầu sai nữa chạy đồng thời thì sao?

Quy tắc đã cho phải tính cả hai và khóa tài khoản. Kiểm tra tuần tự không chứng minh điều này. Cần hai yêu cầu được đồng bộ và quan sát trạng thái cuối: mất một lần cập nhật có thể khiến bộ đếm chỉ còn 4.

Góc nhìn của lập trình viên

Cập nhật bộ đếm và kích hoạt khóa phải nhất quán khi đồng thời. Cũng cần thảo luận rủi ro sản phẩm: khóa theo tài khoản có thể cho phép người ngoài gây gián đoạn cho chủ tài khoản. Đây là vấn đề thiết kế bảo vệ, không phải lý do âm thầm đổi hợp đồng bài tập.

Điểm dễ nhầm: “Năm lỗi” không nêu loại lỗi, khoảng tích lũy hay lúc bắt đầu đếm thời gian. Thiếu chúng, bài kiểm thử mơ hồ.

Tài liệu gốc về chủ đề này

6. HTTP và API: vì sao mã 200 chưa đủ

API là thỏa thuận giữa bên sử dụng và dịch vụ. Kiểm tra cần phương thức, đường dẫn, quyền, header, nội dung yêu cầu, phản hồi và tác động phụ. Trình duyệt chỉ là một bên sử dụng: màn hình hoạt động không chứng minh yêu cầu trực tiếp có cùng mức bảo vệ.

Hợp đồng bài tập: POST /enrollments nhận course_id của khóa học đã xuất bản và tồn tại, tạo một lượt ghi danh cho người dùng hiện tại. Kiểm tra cấu trúc phản hồi và ID, liên kết người dùng với khóa học, gửi lại, khóa học không tồn tại, chưa xuất bản, thiếu trường và user_id của người khác trong body. Khi bị từ chối còn phải chứng minh không có lượt ghi danh mới.

Tính lũy đẳng, hay idempotency, là cùng tác động dự kiến khi lặp yêu cầu giống hệt, không bắt buộc mọi phản hồi giống nhau. POST không tự có tính này. Khóa chống xử lý lặp ở tầng ứng dụng cần hợp đồng về phạm vi, thời gian lưu và trường hợp cùng khóa nhưng body khác. Timeout nghĩa là bên gửi chưa nhận phản hồi, không chứng minh máy chủ chưa ghi dữ liệu.

Câu hỏi phỏng vấn

POST trả 200. Cần kiểm tra gì thêm trước khi kết luận thành công?

Xem phân tích và câu hỏi tiếp theo

Tôi đối chiếu mã với hợp đồng, kiểm tra trường bắt buộc, kiểu, giá trị và không có dữ liệu nhạy cảm ngoài dự kiến. Sau đó đọc trạng thái lưu trữ độc lập: đúng một bản ghi thuộc đúng người dùng và khóa học. Kiểm tra riêng nhánh từ chối và không có tác động phụ. Mã 200 mô tả phản hồi HTTP, không xác nhận toàn bộ điều kiện nghiệp vụ.

Người phỏng vấn hỏi thêm: Sau timeout có thể gửi lại POST ngay không?

Trước hết xác định hợp đồng gửi lại. Nếu hỗ trợ khóa lũy đẳng, dùng lại cùng khóa và body; nếu không, kiểm tra trạng thái thao tác ban đầu bằng ID được quy định. Khóa ngẫu nhiên mới có thể tạo thao tác thứ hai. Cần kiểm tra cả yêu cầu trùng đồng thời, không chỉ gửi lại tuần tự.

Góc nhìn của lập trình viên

Tách kiểm tra cú pháp yêu cầu, xác thực quy tắc nghiệp vụ và lưu dữ liệu. Kiểm thử hợp đồng có thể phát hiện định dạng không tương thích giữa hai bên, nhưng không thay thế kiểm tra quyền thật và dữ liệu đã lưu.

Điểm dễ nhầm: Cùng mã phản hồi không có nghĩa cùng trạng thái. Ngược lại, lần gửi lại có thể trả mã khác nhưng vẫn giữ cùng tác động.

Tài liệu gốc về chủ đề này

7. Xác thực, phân quyền và ranh giới truy cập

Xác thực xác định ai gửi yêu cầu; phân quyền xác định được làm gì. Ẩn nút không phải bảo vệ phía máy chủ. Chuẩn bị hai tài khoản nhân viên kiểm thử A và B do bạn quản lý trong môi trường được phép, khách hàng 101 của A và 202 của B. Hợp đồng: nhân viên chỉ đọc và sửa khách hàng thuộc mình.

Dùng token A đọc 101 để có kiểm chứng dương tính. Sau đó yêu cầu 202, thử sửa và xuất dữ liệu nếu nằm trong phạm vi cho phép. GET bị từ chối chưa đủ: đường ghi có thể kiểm tra quyền khác. Dùng tài khoản B được phép để xác nhận bản ghi không đổi sau thao tác cấm. Không dùng dữ liệu thật của bên thứ ba hay kiểm thử khi chưa được phép.

401 thường liên quan đến thiếu thông tin xác thực phù hợp, 403 là từ chối thực hiện; dịch vụ có thể dùng 404 để che sự tồn tại của tài nguyên. Vì vậy mã mong đợi lấy từ hợp đồng. Thuộc tính quan trọng là không tiết lộ dữ liệu và không tạo tác động bị cấm.

Câu hỏi phỏng vấn

Tại sao token hợp lệ chưa đủ để truy cập GET /customers/202?

Xem phân tích và câu hỏi tiếp theo

Token xác định chủ thể, không chứng minh quyền trên đối tượng này. Tôi kiểm tra vai trò, chủ sở hữu khách hàng và ranh giới tổ chức nếu có. So sánh yêu cầu được phép với bị cấm và đọc body. Đổi ID số sang UUID không thay thế phân quyền: biết ID không được tự động có quyền truy cập.

Người phỏng vấn hỏi thêm: Máy chủ trả 403 nhưng body có tên khách hàng của người khác. Kiểm tra đạt chưa?

Chưa. Mã từ chối không xóa việc tiết lộ dữ liệu trong body. Ghi trường bị lộ, vai trò, tài nguyên và bằng chứng đã ẩn dữ liệu nhạy cảm. Cũng kiểm tra xuất dữ liệu và danh sách trong phạm vi cho phép vì nhiều đường dẫn có thể dùng chung lỗi.

Góc nhìn của lập trình viên

Kiểm tra quyền trên đối tượng phải nằm phía máy chủ cho từng hành động phù hợp. Ma trận hồi quy hữu ích là chủ thể × đối tượng × hành động: chủ sở hữu, nhân viên khác, quản trị; đọc, sửa, xuất.

Điểm dễ nhầm: Kiểm tra đăng nhập thành công không nói gì về truy cập ngang giữa hai nhân viên cùng vai trò.

Tài liệu gốc về chủ đề này

8. SQL khi phỏng vấn: lược đồ, truy vấn và kiểm tra kết quả

Đây là bài viết SQL, không chỉ giải thích bằng lời. PostgreSQL có customers(id PRIMARY KEY, email TEXT NULL) và orders(id PRIMARY KEY, customer_id NOT NULL REFERENCES customers(id), status TEXT NOT NULL). Tìm khách hàng không có bất kỳ đơn nào, rồi riêng biệt tìm nhóm email không rỗng bị trùng. Trong bài này so sánh email phân biệt hoa thường, không bỏ khoảng trắng; NULL và chuỗi rỗng không tính vào trùng. Đơn đã hủy vẫn là đơn hàng.

Dữ liệu: customers gồm (1, a@example.test), (2, b@example.test), (3, a@example.test), (4, NULL), (5, chuỗi rỗng). orders gồm (10, 1, paid), (11, 1, cancelled), (12, 2, cancelled). ID khách hàng không có đơn phải là 3, 4, 5. Nhóm trùng là a@example.test với số lượng 2. Khách hàng 1 cố ý có hai đơn để phát hiện việc phép nối làm nhân số dòng khi đếm khách hàng.

Hai truy vấn PostgreSQL cho lược đồ đã nêu
SELECT c.id
FROM customers AS c
WHERE NOT EXISTS (
    SELECT 1 FROM orders AS o WHERE o.customer_id = c.id
)
ORDER BY c.id;

SELECT email, COUNT(*) AS customer_count
FROM customers
WHERE email IS NOT NULL AND email <> ''
GROUP BY email
HAVING COUNT(*) > 1
ORDER BY email;

Câu hỏi phỏng vấn

Làm sao giải thích hai truy vấn này giải đúng bài toán?

Xem phân tích và câu hỏi tiếp theo

NOT EXISTS giữ khách hàng không có đơn liên quan nào; cố ý không lọc status. Truy vấn thứ hai bỏ địa chỉ thiếu hoặc rỗng, nhóm khách hàng theo email rồi giữ nhóm lớn hơn một. Kiểm tra đúng ID 3, 4, 5, không chỉ có ba dòng. Với email trùng, kiểm tra cả địa chỉ và số lượng 2. Sắp xếp rõ ràng giúp so sánh có thể tái lập.

Người phỏng vấn hỏi thêm: Bây giờ cần khách hàng không có đơn đã thanh toán. Đổi gì?

Thêm AND o.status = 'paid' bên trong NOT EXISTS. Kết quả thành 2, 3, 4, 5: khách hàng 2 có đơn nhưng đã hủy. Đây là câu hỏi nghiệp vụ khác. Với LEFT JOIN, chuyển điều kiện vào WHERE thiếu cân nhắc có thể loại mất các dòng có phía đơn hàng là NULL.

Góc nhìn của lập trình viên

PRIMARY KEY định danh dòng, FOREIGN KEY duy trì quan hệ, NOT NULL cấm thiếu giá trị. Chúng không chứng minh truy vấn nghiệp vụ đúng. Làm rõ chuẩn hóa email trước khi thêm tính duy nhất; lower(trim(email)) thay đổi nghĩa bài toán, không chỉ làm truy vấn nhanh hơn.

Điểm dễ nhầm: Ba dòng trả về có thể là ba khách hàng sai. Cần giá trị mong đợi và trường hợp đối chứng, không chỉ số dòng.

Tài liệu gốc về chủ đề này

9. Giao dịch, xử lý đồng thời và lỗi tích hợp

Giao dịch gom thay đổi cơ sở dữ liệu thành một đơn vị hoàn tất: tập thay đổi cùng được xác nhận hoặc phần chưa hoàn tất bị hoàn tác. Nó không tự bao gồm dịch vụ ngoài. Nếu CRM lưu khách hàng và gửi email, hoàn tác bản ghi cục bộ không thể thu hồi email. Trước tiên xác định thành công nghĩa là gì và khôi phục kết quả một phần thế nào.

ACID gồm bốn thuộc tính: tính nguyên tử tránh lưu một phần; tính nhất quán liên quan đến ràng buộc đã đặt; tính cô lập quy định ảnh hưởng được phép giữa các giao dịch đồng thời; tính bền vững liên quan đến việc giữ thay đổi đã xác nhận. Cần nêu ranh giới: cơ sở dữ liệu không biết mọi quy tắc nghiệp vụ, và cấp độ cô lập không phải lúc nào cũng tương đương chạy tuần tự. Với chuyển khoản, quy định riêng số dư cho phép, bút toán liên quan và hành vi đồng thời.

Quy tắc bài tập: một khách hàng trên mỗi lead_id; lỗi dịch vụ thư không hủy tạo khách hàng mà để thông báo ở trạng thái pending cho phép thử lại. Cho dịch vụ thư timeout sau khi nhận thư. Kiểm tra một khách hàng, tác vụ thông báo được lưu, giới hạn thử lại và không tạo khách hàng thứ hai khi chuyển đổi lại. Cam kết đúng một email cần hợp đồng riêng với nhà cung cấp và chống tác động trùng.

Lỗi tranh chấp cần các thao tác chồng lấn. Nếu cả hai yêu cầu cùng đọc “chưa có khách hàng” rồi cùng chèn, kiểm tra tuần tự vẫn có thể luôn đạt. Ràng buộc duy nhất bảo vệ bất biến, nhưng ứng dụng còn phải xử lý xung đột và trả kết quả nhất quán. Cấp độ cô lập và cách thử lại phụ thuộc cơ sở dữ liệu và thao tác.

Câu hỏi phỏng vấn

Chuyển khoản đã trừ tiền nhưng ghi có thất bại. Kiểm tra gì?

Xem phân tích và câu hỏi tiếp theo

Tôi làm rõ kiến trúc và hợp đồng. Nếu hai lần ghi thuộc một giao dịch cục bộ, gây lỗi giữa hai bước và kiểm tra cả hai được hoàn tác. Nếu qua nhiều dịch vụ, kiểm tra trạng thái chưa hoàn tất và cách khôi phục hoặc bù trừ quy định. Lưu ID thao tác và đối chiếu bút toán, không chỉ số dư cuối. Thử lại không được trừ tiền lần hai; thời gian chờ nhất quán cũng cần được xác định.

Người phỏng vấn hỏi thêm: Timeout có nghĩa thao tác bên ngoài chưa xảy ra?

Không. Phản hồi có thể mất sau khi thực hiện. Cần tra trạng thái, ID thao tác và cơ chế gửi lại an toàn theo hợp đồng. Mô phỏng riêng lỗi trước khi tiếp nhận và mất phản hồi sau thành công vì hậu quả khác nhau.

Góc nhìn của lập trình viên

Thảo luận ranh giới giao dịch, xử lý xung đột và chuyển sự kiện. Outbox có thể lưu ý định phát sự kiện cùng thay đổi nghiệp vụ; chuyển lặp vẫn cần phía nhận chống tác động lặp. Có hàng đợi không đủ để hứa exactly once.

Điểm dễ nhầm: ACID của một cơ sở dữ liệu không bảo đảm tính nguyên tử của cả chuỗi ngân hàng, nhà cung cấp thư và hàng đợi.

Tài liệu gốc về chủ đề này

10. Báo cáo lỗi, severity, priority và quyết định phát hành

Báo cáo hữu ích giúp tái hiện khác biệt: phiên bản, môi trường, vai trò, dữ liệu đầu, thao tác chính xác, kỳ vọng có căn cứ, thực tế và bằng chứng. “Checkout đôi khi lỗi” không nêu bước hay biểu hiện. Checkout là hoàn tất đặt hàng; chẳng hạn hãy nói API trả 500 sau xác nhận giỏ, đơn đã lưu nhưng trang đề nghị thử lại.

Severity mô tả mức ảnh hưởng; priority mô tả độ khẩn cấp trong bối cảnh. Lỗi hiển thị trên trang chuẩn bị chạy chiến dịch có thể gấp, còn hỏng dữ liệu hiếm gặp vẫn nghiêm trọng dù ít người bị ảnh hưởng. Thang đo và quyền quyết định do đội thống nhất, không phải bảng xếp hạng chung trên mạng.

Khi hồi quy thiếu thời gian, xác định luồng thay đổi, dữ liệu liên quan, quyền và tác động khó đảo ngược. Với thay đổi chuyển đổi CRM, trùng khách hàng, mất liên kết lead và truy cập trái phép có thể được ưu tiên. Báo cáo kiểm tra đã làm, lỗi đã biết, giới hạn môi trường và rủi ro chưa kiểm tra. Quyết định phát hành cần bằng chứng đó, không chỉ phần trăm bài kiểm thử đạt.

Câu hỏi phỏng vấn

Lỗi xuất hiện một trong mười lần. Làm sao báo cáo có ích?

Xem phân tích và câu hỏi tiếp theo

Tôi mô tả mười lần thử và khác biệt điều kiện, thời gian yêu cầu lỗi, bản dựng, request ID, phản hồi và trạng thái đơn sau đó. Đính kèm log đã ẩn dữ liệu nhạy cảm hoặc trace nếu có. Tách sự thật khỏi giả thuyết: yêu cầu đồng thời khác có thể liên quan nhưng chưa được chứng minh. Nêu rủi ro tạo đơn trùng và cách thử tái hiện cụ thể.

Người phỏng vấn hỏi thêm: Lập trình viên nói “máy tôi vẫn chạy”. Tiếp theo làm gì?

So sánh phiên bản, cấu hình, vai trò, dữ liệu và thứ tự thao tác. Dùng request ID tìm lần cụ thể rồi đối chiếu quan sát từ các thành phần. Không thay bằng chứng bằng tranh luận; nếu chưa khôi phục điều kiện, giữ rõ trạng thái đang điều tra và các quan sát đã có.

Góc nhìn của lập trình viên

Mã tương quan kết nối bản ghi của một thao tác giữa các thành phần. Log cần hỗ trợ điều tra mà không lưu mật khẩu, token hoặc dữ liệu cá nhân không cần thiết.

Điểm dễ nhầm: Tần suất tái hiện không phải mức ảnh hưởng. Trừ tiền hai lần hiếm gặp không trở thành lỗi thẩm mỹ.

Tài liệu gốc về chủ đề này

11. Lý thuyết cho lập trình viên: test double, độ bao phủ, TDD và CI

Kiểm thử tự động cần chuẩn bị có kiểm soát, hành động và xác nhận kết quả quan sát được. Với CRM, tạo lead mới và tài khoản sở hữu, chuyển đổi rồi xác nhận đúng một khách hàng với liên kết phù hợp. Cô lập dữ liệu: không phụ thuộc bài kiểm thử bên cạnh chạy trước. Dọn dữ liệu hoặc dùng vùng dữ liệu riêng tốt hơn tên ngẫu nhiên chỉ giảm khả năng trùng.

Test double thay thế một thành phần thật. Stub trả phản hồi chuẩn bị sẵn; mock thường còn xác nhận tương tác mong đợi; fake cung cấp cách triển khai đơn giản nhưng hoạt động. Thuật ngữ có thể khác giữa thư viện. Cần nói rõ thay thế gì và lỗi nào vì thế không còn nhìn thấy. Stub thư giúp tạo timeout nhưng không chứng minh tương thích với nhà cung cấp thật.

TDD dùng vòng lặp ngắn: bài kiểm thử thể hiện hành vi cần có và thất bại đúng nguyên nhân, triển khai tối thiểu làm nó đạt, rồi cải thiện mã mà vẫn giữ kiểm tra. TDD không bảo đảm yêu cầu tốt. CI, tích hợp liên tục, tự động chạy kiểm tra khi có thay đổi; môi trường tái lập được và bằng chứng lỗi rõ ràng làm phản hồi đáng tin.

Câu hỏi phỏng vấn

Độ bao phủ mã 100%. Tại sao vẫn có thể còn lỗi?

Xem phân tích và câu hỏi tiếp theo

Chỉ số đo phần mã đã chạy, không đo độ đầy đủ của yêu cầu hay chất lượng xác nhận. Một bài có thể chạy qua nhánh mà không kiểm tra điều hữu ích. Quy tắc bị bỏ quên có thể chưa tồn tại trong mã. Tôi xem xác nhận giá trị, trường hợp âm, tương tác và đồng thời. Thử đổi quy tắc trong suy nghĩ hoặc dùng mutation testing giúp đánh giá bài kiểm thử có phát hiện thay đổi hành vi quan trọng không.

Người phỏng vấn hỏi thêm: Bài kiểm thử đôi khi lỗi trong CI rồi đạt khi chạy lại. Thêm sleep?

Trước tiên điều tra dữ liệu dùng chung, thứ tự chạy, điều kiện bất đồng bộ, thời gian và mạng. Chờ cố định có thể che lỗi tranh chấp và làm chậm cả bộ. Với UI nên chờ trạng thái quan sát cụ thể trong thời hạn giới hạn. Đạt khi chạy lại là thông tin chẩn đoán, không chứng minh đã sửa tính bất ổn.

Góc nhìn của lập trình viên

Khi rà soát, hỏi bài có thất bại khi lỗi thật xuất hiện không, có giải thích được nguyên nhân không, chạy riêng và song song được không. Đừng chỉ kiểm tra lời gọi nội bộ nếu điều quan trọng là kết quả cho người dùng. Lưu trace và báo cáo lỗi CI, không lưu bí mật.

Điểm dễ nhầm: Mock interview là phỏng vấn thử. Mock trong kiểm thử tự động là một dạng thay thế thành phần: cùng từ tiếng Anh nhưng khác ngữ cảnh.

Tài liệu gốc về chủ đề này

12. Hiệu năng, khôi phục và cách lập luận ở mức Middle

Kiểm thử tải đánh giá cấu hình làm việc đã nêu; kiểm thử sức chịu đựng tìm giới hạn và thất bại; chạy kéo dài có thể lộ tích lũy tài nguyên. Số người dùng và yêu cầu mỗi giây không tương đương: người này có thể chờ, người khác gửi nhiều yêu cầu. Phải xác định thao tác, cường độ, dữ liệu, thời lượng và môi trường.

Với LMS của bài tập, giả sử 100 học viên đang đọc bài, trung bình mỗi người gửi một yêu cầu mỗi mười giây; thêm 20 người nộp đáp án đồng thời. Thay bằng một trăm GET giống nhau không chứng minh hệ thống sẵn sàng. Ngoài độ trễ, kiểm tra lỗi, lưu lượt làm bài, hàng đợi xử lý và phục hồi khi giảm tải.

RPO là khoảng dữ liệu có thể mất tính theo thời gian; RTO là thời gian khôi phục mục tiêu. Sự cố lúc 10:00, bản sao dùng được từ 09:50 nghĩa là mất mười phút cuối. Khôi phục xong lúc 10:40 mất bốn mươi phút. Cần so với mục tiêu đã thống nhất. Có tệp sao lưu không chứng minh có thể khôi phục dữ liệu nhất quán.

Câu hỏi phỏng vấn

Trả lời “khi nào dừng kiểm thử” thế nào mà không nói “khi hết lỗi”?

Xem phân tích và câu hỏi tiếp theo

Tôi nêu tiêu chí kết thúc đã thống nhất: luồng quan trọng được kiểm tra, trạng thái lỗi chấp nhận được, rủi ro đã xử lý và giới hạn đã biết. Sau đó trình bày kết quả thực tế và rủi ro còn lại. Thay đổi phạm vi hay môi trường có thể yêu cầu xem lại kết luận. Chưa phát hiện lỗi không có nghĩa không còn lỗi; phát hành là quyết định trong điều kiện bất định đã biết.

Người phỏng vấn hỏi thêm: Còn 30 phút phát hành nhưng hồi quy đầy đủ mất một ngày. Làm gì?

Làm rõ thay đổi và tác động thất bại, ưu tiên bộ ngắn theo rủi ro quan trọng, nói rõ phần chưa kiểm tra. Di trú dữ liệu khó đảo ngược hoặc thao tác tài chính có thể cần hoãn. Kế hoạch quay lại, giám sát sau phát hành và triển khai giới hạn giúp quản lý rủi ro nhưng không biến hành vi chưa kiểm tra thành đã xác nhận.

Góc nhìn của lập trình viên

Với thay đổi lược đồ, kiểm tra tương thích phiên bản ứng dụng cũ và mới, thứ tự di trú và khả năng khôi phục. Quay lại mã cũ không nhất thiết đảo ngược biến đổi dữ liệu. Thực hiện khôi phục trên bản sao cô lập hữu ích hơn chỉ nói đã có kế hoạch.

Điểm dễ nhầm: Câu trả lời Middle tốt không nhất thiết nhanh hơn. Nó làm rõ giả định, ưu tiên và giới hạn của bằng chứng.

Tài liệu gốc về chủ đề này

Cách học mà không thuộc lòng câu trả lời

  1. Lượt đầu: giải thích một chủ đề bằng lời của mình và liệt kê thuật ngữ chưa hiểu. Đừng chạy qua hai mươi định nghĩa liên tiếp.
  2. Thực hành: biến ví dụ thành chuẩn bị → hành động → kỳ vọng → bằng chứng. Với SQL, chạy truy vấn trong cơ sở dữ liệu học tập riêng theo dữ liệu đã cho.
  3. Tự kiểm tra: trả lời câu chính và câu hỏi thêm trước khi mở phân tích. So sánh quy tắc, ví dụ, quan sát và giới hạn, không so từng chữ.
  4. Chuyển ngữ cảnh: thay cửa hàng bằng CRM hoặc LMS. Giải thích phương pháp nào giữ nguyên, quy tắc nghiệp vụ nào đổi. Điều này kiểm tra hiểu biết tốt hơn đọc lại văn bản.
  5. Ôn lại: buổi sau phân tích cùng rủi ro với dữ liệu khác mà không xem gợi ý. Giải thích được vì sao đáp án khác sai là dấu hiệu hiểu vững hơn.

Tự đánh giá bốn điểm: quy tắc rõ, dữ liệu cụ thể, kết quả quan sát được và giới hạn trung thực. Đây là khung tự kiểm tra, không phải điểm năng lực tự động. Có thể mở phân tích không cần đăng ký; trang này không lưu riêng câu trả lời.

Tiếp tục với 40 câu hỏi phỏng vấn thử QA

Đã có quyền truy cập? Mở lý thuyết trong khu vực học tập

Câu hỏi thường gặp khi chuẩn bị phỏng vấn

Junior QA nên học gì trước?

Bắt đầu từ yêu cầu, kết quả mong đợi, thiết kế kiểm thử, cấp độ kiểm tra và báo cáo lỗi. Kết nối chúng với HTTP, quyền truy cập và SQL đơn giản. Mỗi thuật ngữ cần một ví dụ tự phân tích. Điều chỉnh ưu tiên theo mô tả việc làm, không theo độ dài danh sách chung.

Câu trả lời Middle khác Junior thế nào?

Tên cấp bậc khác nhau giữa công ty. Định hướng hữu ích là Junior giải thích phép kiểm tra trong điều kiện rõ, còn Middle bàn thêm phụ thuộc, rủi ro, chi phí, đồng thời và giới hạn kết quả. Đây không phải thang chính thức hay yêu cầu biết mọi công nghệ.

Lập trình viên có cần lý thuyết kiểm thử không?

Có. Nó giúp chọn ranh giới kiểm tra, xác định kỳ vọng độc lập với triển khai và biết stub không chứng minh được gì. Khi phỏng vấn lập trình viên, giải thích ranh giới giao dịch, cô lập dữ liệu kiểm thử, bài kiểm thử bất ổn và phản hồi CI rất hữu ích. Bài này không thay thế chuẩn bị về ngôn ngữ cụ thể.

Có cần học thuộc đáp án và lấy chứng chỉ?

Câu trả lời thuộc lòng dễ mất tác dụng khi bị hỏi thêm. Hãy dựng lại lập luận với dữ liệu khác. Một vị trí có thể yêu cầu chứng chỉ nhưng nó không thay thế thực hành; không cần mua chứng chỉ để sử dụng tài liệu này.

Lý thuyết trở thành công cụ làm việc khi giúp chọn phép kiểm tra tiếp theo và giải thích kết quả. Tự xây dựng một bản phân tích có dữ liệu và bằng chứng, rồi chuyển sang rủi ro kế tiếp.

Xem gói đăng ký thực hành Bài tiếp theo

← Tất cả bài viết