Interview Experience
MIỄN PHÍSoftware Engineer
Mid-level · Technology / Software · Việt Nam
Bối cảnh trải nghiệm
Coding mở màn bằng LRU Cache, còn phần khó hơn nằm ở bài Chat System nơi interviewer liên tục đào sâu WebSocket, Message Queue, Database và Data Partitioning.
Phỏng vấn Software Engineer tại Công ty G: LRU Cache, Chat System và System Design
My Experience
Tổng quan
Đây là trải nghiệm phỏng vấn cho vị trí Software Engineer tại Công ty G, gồm 3 vòng:
Coding → System Design → Culture Fit
Hai vòng đầu có cấu trúc khá rõ: Round 1 kiểm tra khả năng giải quyết algorithm và thiết kế data structure, trong khi Round 2 chuyển sang một bài Chat System tương tự WhatsApp.
Điểm đáng chú ý là system design không chỉ dừng ở việc vẽ architecture. Interviewer liên tục hỏi sâu vào các component và quyết định kỹ thuật phía sau như HTTP vs WebSocket, Message Queue, SQL vs NoSQL, Database Partitioning và gRPC.
Theo chia sẻ của ứng viên, background trước đó không quá mạnh về backend và systems. Vì vậy, ứng viên chủ yếu chuẩn bị dựa trên course System Design của EP và sách của Alex Xu, đồng thời review lại các distributed-system components trước interview.
Round 1 — Coding
Thời lượng khoảng 1 giờ, coding trực tiếp trên Codility.
Ứng viên được hỏi 2 bài ở mức tương đương Medium trên LeetCode và đều là những dạng bài khá phổ biến.
Q1 — Minimum Number of Steps to Make Two Strings Anagram
Bài toán cho hai string s và t, cùng một số k.
Trong mỗi step, có thể chọn một character trong t và thay thế bằng character khác. Yêu cầu kiểm tra liệu có thể biến t thành một anagram của s với không quá k phép thay đổi hay không.
Bài toán này có thể giải bằng cách đếm frequency của từng character trong hai string, sau đó xác định số lượng character đang bị thiếu/thừa.
Điểm quan trọng là không cần thử từng phép replacement. Chỉ cần nhìn vào frequency difference giữa hai string là có thể xác định số replacement tối thiểu cần thiết.
Nếu s và t có cùng độ dài, số replacement tối thiểu chính là tổng phần thiếu của các character khi so sánh frequency của hai string.
Q2 — LRU Cache
Bài thứ hai là Design a Least Recently Used (LRU) Cache.
Đây là bài kinh điển để kiểm tra khả năng kết hợp nhiều data structures nhằm đạt complexity tốt cho cả get và put.
Approach phổ biến là kết hợp:
Hash Map + Doubly Linked List
- Hash Map giúp tìm node theo key trong
O(1). - Doubly Linked List duy trì thứ tự sử dụng gần đây.
- Node vừa được access sẽ được đưa lên đầu.
- Khi cache vượt capacity, node ở cuối danh sách — tức least recently used — sẽ bị remove.
Với thiết kế này, cả get và put đều có thể đạt O(1) amortized/expected theo cách triển khai thông thường.
Kết quả: chưa được ứng viên nêu rõ trong source.
Round 2 — System Design
Đây là vòng có phần discussion kéo dài khoảng 1 giờ 15 phút, ngoài khoảng 15 phút đầu dành cho introduction và experience.
Introduction — khoảng 15 phút
Interviewer bắt đầu bằng các câu hỏi về experience và motivation, chẳng hạn:
- What is the most interesting task you have worked on?
- What was the challenge?
- Why are you applying to Công ty G?
- Các câu hỏi liên quan đến background và experience.
Sau phần introduction, interview chuyển sang system design.
Design a Chat System
Problem yêu cầu thiết kế một hệ thống chat tương tự WhatsApp, nhưng scope được giới hạn vào 1-on-1 chat.
Các requirement chính:
- Chỉ hỗ trợ chat giữa 2 người.
- Chỉ hỗ trợ text message.
- Mỗi message tối đa 1000 characters.
- Khi user online, message cần được deliver.
- Khi user offline, các message gửi tới user phải được lưu lại và deliver khi user online trở lại.
- Offline user cần nhận notification khi có message mới.
- Hệ thống cần thể hiện trạng thái online/offline của user.
Đây là một bài system design khá phổ biến, nhưng phần thú vị nằm ở việc requirement có thể dẫn đến nhiều vấn đề khác nhau: realtime connection, message persistence, offline delivery, notification và consistency giữa trạng thái của user với message state.
Cách tiếp cận System Design
Ứng viên sử dụng framework 7-step system design đã học trong course System Design của EP.
Tuy nhiên, interviewer muốn đẩy nhanh tiến độ nên yêu cầu bỏ qua hai phần:
- Estimation
- API Design
Thời gian còn lại tập trung nhiều hơn vào architecture và technical discussion.
Theo chia sẻ của ứng viên, interviewer cũng kiểm tra khá nhiều kiến thức về các distributed-system components trong quá trình design.
Vì vậy, việc hiểu từng component làm gì quan trọng không kém việc biết cách vẽ chúng vào architecture.
HTTP vs WebSocket
Một câu hỏi được interviewer đưa ra là:
What is the difference between HTTP and WebSocket?
Đây là distinction quan trọng đối với chat system.
HTTP request/response phù hợp với các interaction mà client gửi request và server trả response. Trong khi đó, WebSocket cung cấp một connection hai chiều lâu dài, cho phép server chủ động gửi data tới client khi có event mới.
Với realtime chat, WebSocket có thể phù hợp cho real-time message delivery và các event như online/offline status.
Tuy nhiên, WebSocket không tự giải quyết bài toán persistence hay offline delivery. Khi user mất connection, hệ thống vẫn cần một cơ chế lưu message và xác định message nào chưa được deliver.
Message Queue
Interviewer tiếp tục hỏi:
What can we achieve by using a message queue?
Trong chat system, message queue có thể đóng vai trò trung gian giữa việc nhận message và các bước xử lý phía sau.
Một số lợi ích có thể có:
- Decouple các components.
- Buffer traffic spike.
- Cho phép consumer xử lý message asynchronously.
- Hỗ trợ retry trong những workflow phù hợp.
- Giảm coupling giữa message ingestion và downstream processing.
Tuy nhiên, việc thêm queue cũng tạo ra trade-off về ordering, delivery semantics, retry và operational complexity.
Vì vậy, không nên mặc định rằng cứ có Message Queue thì architecture sẽ tốt hơn. Cần xác định vấn đề nào queue đang giải quyết.
SQL hay NoSQL?
Interviewer hỏi:
What is your choice for a database, SQL or NoSQL? Why?
Đây là dạng câu hỏi không có một đáp án tuyệt đối.
Với chat system, quyết định database phụ thuộc vào:
- Data model
- Access pattern
- Message volume
- Query pattern
- Consistency requirements
- Scale
- Operational requirements
Điểm interviewer muốn kiểm tra không chỉ là ứng viên chọn SQL hay NoSQL, mà là lý do phía sau lựa chọn đó.
Ví dụ, nếu workload chủ yếu là lưu và đọc message theo conversation/user với scale lớn, một database phù hợp với access pattern và khả năng partitioning tốt có thể trở thành lựa chọn đáng cân nhắc.
Database Partitioning
Một câu hỏi khác đi sâu hơn:
Why do we need to partition data in a database? For a chat system, how would you partition the message database?
Partitioning thường được sử dụng khi một dataset hoặc workload đã đủ lớn để một database node không còn phù hợp với yêu cầu về storage, throughput hoặc scalability.
Với chat system, một hướng suy nghĩ tự nhiên là partition theo conversation / user / conversation ID, tùy access pattern.
Điểm cần cân nhắc là các query phổ biến nhất của hệ thống.
Nếu phần lớn request có dạng:
“Lấy messages của conversation X”
thì partition key nên hỗ trợ tốt access pattern này.
Nhưng partitioning cũng kéo theo những vấn đề khác như hot partition, rebalancing và các query cần truy cập nhiều partition.
Offline Message Delivery
Interviewer hỏi:
How do you deliver messages that a user received while offline when they come online?
Đây là một trong những phần quan trọng nhất của bài toán.
Khi user offline, message không thể được deliver trực tiếp qua realtime connection. Vì vậy, message cần được persist trước.
Khi user reconnect:
- Client thiết lập connection mới.
- Server xác định các message chưa được deliver/acknowledge theo cơ chế state mà hệ thống sử dụng.
- Server gửi các message pending.
- Client acknowledge việc nhận message.
- Server cập nhật delivery state tương ứng.
Trong production, phần này còn phải xử lý reconnect, duplicate delivery và idempotency.
Đặc biệt, “đã gửi tới server”, “đã deliver tới device” và “đã được user đọc” là những trạng thái khác nhau. Một design tốt cần định nghĩa rõ state machine thay vì gom tất cả thành một trạng thái sent.
gRPC và WebSocket
Interviewer tiếp tục hỏi:
What is gRPC? Can we use gRPC for user connection to a chat system instead of using WebSocket?
Đây là câu hỏi khá thú vị vì nó kiểm tra xem ứng viên có hiểu bản chất của từng communication protocol hay chỉ nhớ technology names.
gRPC thường được sử dụng cho service-to-service communication và dựa trên HTTP/2, với contract thường được định nghĩa bằng Protocol Buffers.
gRPC cũng hỗ trợ streaming, nên về mặt kỹ thuật không nên đơn giản hóa thành “gRPC chỉ là request-response”.
Tuy nhiên, với client-to-server realtime chat, WebSocket thường là một lựa chọn tự nhiên vì browser/client có thể duy trì một bidirectional connection và server chủ động push event xuống client.
Nếu cân nhắc gRPC cho client connection, cần xem xét thêm client/platform support, browser constraints và cách triển khai streaming.
Điểm quan trọng ở đây không phải trả lời đơn giản “được” hay “không được”, mà phải giải thích protocol nào phù hợp hơn với communication pattern và deployment environment đang xét.
Interview Intelligence
1. Chat System thực chất kiểm tra nhiều fundamentals cùng lúc
Bề ngoài đây là một bài “design WhatsApp”, nhưng interviewer có thể dùng nó để kiểm tra rất nhiều kiến thức:
Realtime Communication → Message Processing → Persistence → Database → Partitioning → Notification → Offline Delivery → Distributed Systems
Vì vậy, việc học thuộc một architecture diagram không đủ.
Quan trọng hơn là hiểu từng requirement dẫn tới component nào và component đó giải quyết vấn đề gì.
2. Online/offline không chỉ là một boolean
Một design đơn giản có thể bắt đầu bằng:
user.isOnline = true/false
Nhưng production system phức tạp hơn.
Connection có thể bị mất đột ngột, user có thể đăng nhập trên nhiều device, network có thể unstable và một connection có thể timeout mà server chưa biết ngay.
Vì vậy, nếu interviewer đào sâu, có thể phải thảo luận thêm về heartbeat, connection timeout, presence service và multi-device state.
3. Message delivery cần định nghĩa rõ semantics
Một trong những điểm dễ bị bỏ qua khi design chat system là “message delivered” nghĩa là gì.
Có thể phân biệt:
- Sent: server đã nhận message.
- Persisted: message đã được lưu.
- Delivered: message đã được gửi tới client/device.
- Read: user đã mở hoặc đọc message.
Khi đã phân biệt được các state này, những câu hỏi về offline delivery, retry, reconnect và duplicate message sẽ dễ reason hơn rất nhiều.
4. Message Queue không phải solution cho mọi thứ
Queue có thể giúp decouple components và absorb traffic spike, nhưng nó cũng đưa vào architecture những vấn đề mới.
Ví dụ:
- Message ordering
- Duplicate processing
- Retry
- Dead-letter handling
- Consumer lag
- Delivery semantics
Với chat system, ordering đặc biệt đáng quan tâm nếu requirement yêu cầu messages trong cùng conversation phải xuất hiện đúng thứ tự.
5. Partitioning phải đi theo access pattern
Câu hỏi “partition database theo gì?” không nên trả lời bằng một keyword duy nhất.
Hãy bắt đầu từ:
Application thường query data như thế nào?
Nếu workload chủ yếu là lấy message history của một conversation, partition strategy nên phục vụ access pattern đó.
Sau đó mới tiếp tục kiểm tra:
- Một partition có bị quá nóng không?
- Conversation lớn nhất sẽ đi đâu?
- Có cần time-based partitioning không?
- Query có cần cross-partition không?
- Khi scale thêm node thì data được rebalance như thế nào?
Đây mới là phần system design interviewer thường muốn nghe ở level có kinh nghiệm.
6. Đừng học system design theo một architecture duy nhất
Ứng viên đã chuẩn bị theo một framework và một số tài liệu system design, nhưng interviewer vẫn chủ động bỏ qua Estimation và API Design để đi sâu vào component knowledge.
Đây là một signal hữu ích khi chuẩn bị interview:
Không nên chỉ nhớ “Chat System gồm WebSocket + Kafka + Redis + Database”.
Thay vào đó, cần hiểu:
Requirement → Problem → Mechanism → Component → Trade-off
Khi requirement thay đổi, architecture cũng phải thay đổi theo.
Nhìn lại interview process
Hai vòng đầu tạo thành một progression khá rõ:
Coding fundamentals → System design reasoning
Round 1 kiểm tra khả năng giải quyết algorithm và data structure thông qua Anagram và LRU Cache.
Round 2 chuyển sang một problem lớn hơn, nơi ứng viên phải reason về realtime communication, persistence, distributed components và database architecture.
Theo chia sẻ của ứng viên, background backend/systems chưa phải điểm mạnh, nên phần chuẩn bị system design tập trung khá nhiều vào framework và tài liệu học trước interview.
Điểm đáng chú ý là interviewer không chỉ đánh giá diagram cuối cùng, mà liên tục dùng follow-up questions để kiểm tra xem ứng viên có thực sự hiểu vì sao component đó tồn tại và trade-off phía sau lựa chọn của mình hay không.
Quy trình phỏng vấn
Quá trình phỏng vấn
Quy trình tại Công ty G gồm 3 vòng:
Coding → System Design → Culture Fit
Round 1 — Coding
Thời lượng khoảng 1 giờ, live coding trên Codility với 2 bài:
- Minimum Number of Steps to Make Two Strings Anagram
- LRU Cache
Hai bài được ứng viên đánh giá ở mức tương đương Medium trên LeetCode và khá phổ biến.
Bài Anagram tập trung vào frequency counting và tìm số replacement tối thiểu.
Bài LRU Cache yêu cầu kết hợp Hash Map + Doubly Linked List để hỗ trợ get và put với complexity O(1) theo thiết kế thông thường.
Round 2 — System Design
Phần introduction kéo dài khoảng 15 phút, tập trung vào:
- Interesting task đã từng làm
- Technical challenges
- Motivation ứng tuyển
- Past experience
Sau đó là khoảng 1 giờ 15 phút system design.
Problem: Design a Chat System tương tự WhatsApp, scope 1-on-1 text chat.
Requirement chính:
- Text message tối đa 1000 characters
- Realtime delivery khi user online
- Lưu message khi user offline
- Deliver offline messages khi user quay lại
- Notification cho offline user
- Online/offline status
Interviewer yêu cầu bỏ qua Estimation và API Design để tập trung vào architecture và technical discussion.
Trong quá trình design, interviewer đào sâu vào:
- HTTP vs WebSocket
- Message Queue
- SQL vs NoSQL
- Database Partitioning
- Offline Message Delivery
- gRPC vs WebSocket
- Các distributed-system components
Theo chia sẻ của ứng viên, đây là phần cần khá nhiều kiến thức backend/system fundamentals. Ứng viên chuẩn bị chủ yếu bằng course System Design của EP và sách của Alex Xu.
Round 3 — Culture Fit
Round 3 là Culture Fit, thời lượng khoảng 1 giờ.
Source hiện tại chưa ghi lại chi tiết các câu hỏi hoặc nội dung discussion của vòng này.
Questions I Remember
Round 1 — Coding
- Minimum Number of Steps to Make Two Strings Anagram
- Design a Least Recently Used (LRU) Cache
Round 2 — System Design
Chat System
- Design a chat system similar to WhatsApp
- 1-on-1 chat
- Text messages, maximum 1000 characters
- Deliver messages when users are online
- Offline message delivery
- Notify offline users of new messages
- Online/offline user status
System Fundamentals
- What is the difference between HTTP and WebSocket?
- What can we achieve by using a Message Queue?
- What is your choice for a database, SQL or NoSQL? Why?
- Why do we need to partition data in a database?
- For a chat system, how would you partition the message database?
- How do you deliver messages that a user received while offline when they come online?
- What is gRPC?
- Can we use gRPC for user connection to a chat system instead of WebSocket?
Round 3 — Culture Fit
- Source chưa ghi lại chi tiết câu hỏi.
Outcome
Kết quả
Source hiện tại chưa ghi rõ kết quả cuối cùng của interview process.
Interview loop gồm 3 vòng:
Coding → System Design → Culture Fit
Anonymous contributor
✓ Reviewed by EmpSignal
Trải nghiệm thật, được EmpSignal kiểm duyệt.
Muốn đọc thêm những trải nghiệm như thế này?
Khám phá thư viện trải nghiệm dành cho thành viên EmpSignal.
Truy cập những câu chuyện chuyên sâu từ cộng đồng người đi làm.
Khám phá membership →Trải nghiệm liên quan
Gợi ý dựa trên chủ đề, ngành và cấp bậc tương tự bài bạn vừa đọc.
Khám phá thêm trên EmpSignal
Ngoài đọc trải nghiệm, đây là những cách khác để kết nối và chuẩn bị tốt hơn.
Signal Talk
Ghép 1:1 ẩn danh với người cùng chủ đề — không lộ email, luôn là cuộc trò chuyện thật.
Tìm người để nói chuyện →Signal Interview Prep AI
EmpSignal AI đọc job description, đối chiếu với trải nghiệm phỏng vấn thật, rồi chỉ ra câu hỏi, stories và điểm dễ bị hỏi sâu.
home.pillars.prepBadgeBạn cũng có một câu chuyện?
Chia sẻ trải nghiệm phỏng vấn hoặc nơi làm việc của bạn — ẩn danh, không lộ email hay tên công ty.