Search…

Các Kiến Thức Cần Chuẩn Bị Cho Buổi Phỏng Vấn C++

10/10/202010 min read
Các kiến thức cần chuẩn bị cho buổi phỏng vấn C++ và cho công việc C++.

Mặc dù ngôn ngữ lập trình C++ vẫn được đánh giá là rất khó nhưng C++ luôn có được các điểm ưu việt về tính hiệu năng và rất phù hợp với những công việc như sau:

  • Embedded - lập trình nhúng.
  • Automotive - các công ty Việt Nam hoặc các tập đoàn đa quốc gia với các công ty con ngành sản xuất ô tô.
  • Game - các công ty phát triển game trên nền tảng C++.

Đúc kết từ 8 năm làm việc, tuyển dụng, đào tạo lập trình C++ và dựa vào nhiều cuộc phỏng vấn với các kỹ sư trong các công ty phát triển sản phẩm cần C++ như: Gameloft, VNG, Bosch, FPT Software, ..., tôi quyết định viết bài này để có thể hệ thống sát với thực tế các kiến thức hiện tại công ty đang cần ở ứng viên dù bạn đang ứng tuyển cho vị trí lập trình hay kiểm thử.

Cần lưu ý rằng, C++ và giải thuật luôn được phỏng vấn và sử dụng kèm theo nên trong cuộc phỏng vấn và công việc thực tế bạn cũng sẽ nhận được những câu hỏi hoặc vấn đề về giải thuật. Trong giới hạn về nội dung C++, STDIO Training sẽ chia sẻ nội dung về các câu hỏi phỏng vấn giải thuật ở 1 bài viết khác.

Các kiến thức tổng hợp bên dưới phù hợp với fresher, junior và cả senior, khi hoàn thiện tất cả các kiến thức bên dưới, level của bạn có thể được nâng cao rất nhiều.

  1. Dynamic allocation & Regular pointer
  2. Object Oriented Programming
  3. Type casting
  4. Preprocessing & directive
  5. Static library & Dynamic (Shared) library
  6. Template & STL
  7. Exception handling
  8. C++11 và C++1x
  9. Multithreading
  10. Design Patterns
  11. GNU Compiler - Building process & Make file
  12. Performance

1. Dynamic allocation & Regular pointer

Khi đề cập đến ngữ C hay C++ không thể không đề cập đến tính năng cấp phát động (dynamic allocation) và vai trò của con trỏ (pointer).

  • Nếu là C bạn có thể tìm hiểu về <stdlib.h> với 2 hàm malloc/free để cấp phát và giải phóng bộ nhớ.
  • Tương tự như vậy với C++ có từ khóa new/delete để cấp phát và giải phóng bộ nhớ, bên cạnh đó có thể gọi được constructor và destructor của các đối tượng.

Với pointer, bạn cũng cần tìm hiểu kỹ các điều sau:

  • Cách thức tính toán địa chỉ với các kiểu dữ liệu khác nhau.
  • Con trỏ hàm cũng rất có giá trị để hiện thực các callback, late binding.

2. Object Oriented Programming

Với các ngôn ngữ lập trình hiện đại, không thể không đề cập đến lập trình hướng đối tượng (OOP).

Ngoài việc hiểu được 4 tính chất cơ bản của lập trình hướng đối tượng là gì: tính trừu tượng (abstraction), tính đóng gói (encapsulation), tính kế thừa (inheritance) và tính đa hình (polymorphism).

Nâng cao hơn, nếu bạn có thể hiểu được vì sao nó ra đời hoặc sử dụng khi nào, đây là sẽ là điểm cộng cho buổi phỏng vấn và giúp bạn có thể làm việc tốt hơn.

Ngoài ra, OOP còn là tiền đề để có thể hiện thực các Design Pattern, hoặc các thể hiện trong UML, do đó bạn hãy cố gắng để nắm vững nó.

3. Type casting

Hay còn gọi là chuyển kiểu dữ liệu, đây là các tính năng dễ học, ít phải sử dụng đến tư duy, ngoài chuyển kiểu bằng cú pháp đặt kiểu dữ liệu trước tên biến hoặc giá trị, C++ chia điều này thành 4 cách thức chuyển kiểu và tùy vào trường hợp mà sử dụng để mang lại tính tường minh, an toàn hơn cho ứng dụng.

  • const_cast<>
  • reinterpret_cast<>
  • static_cast<>
  • dynamic_cast<>

4. Preprocessing & directive

Preprocessing và các directive mà bạn thường thấy như: #include, #if, #define, ... tạo thêm sự uyển chuyển trong tổ chức chương trình.

Khác với các ngôn ngữ khác như reflection của Java, C++ không có được tính năng "cấu hình" tại thời điểm thực thi, nhưng ở thời điểm biên dịch, tính năng preprocess cũng đủ để xây dựng 1 hệ thống cấu hình hoặc thay đổi cấu hình rất nhanh chóng và tinh gọn.

5. Static library & Dynamic (Shared) library

Không chỉ sử dụng các mã máy từ việc biên dịch các file .c/.cpp, C++ hỗ trợ việc tích hợp hoặc sử dụng các mã thực thi đã được biên dịch sẵn và đưa vào dự án mà không cần biên dịch lại, trường hợp đó là sử dụng static library hoặc dynamic library.

  • Trên hệ điều hành Windows bạn có thể thấy các file quen thuộc như .lib/.dll.
  • Tương tự với Linux bạn có thể thấy .a/.so.

Trong dự án lớn, bạn cũng sẽ được yêu cầu tích hợp các thư viện này vào dự án và sử dụng nó để:

  • Rút ngắn thời gian biên dịch.
  • Chia để trị, tránh sự phụ thuộc.
  • Chia nhỏ file nhị phân.
  • Tạo tính tái sử dụng.

6. Template & STL

Với template, rất hữu ích cho các dạng project framework, core,... vì nó tạo ra tính biến đổi 1 hàm, hay class tùy thuộc vào ngữ cảnh sử dụng, nếu phải xây dựng các framework thì template dường như không thể thiếu và được sử dụng rất nhiều.

STL hay Standard Template Library ngoài việc được xây dựng dựa trên template để thỏa mãn nhiều kiểu dữ liệu khác nhau, có thể hiểu STL cơ bản giải quyết được các loại dữ liệu dạng mắc xích như:

  • Danh sách liên kết - list<>
  • Hàng đợi hoặc ngăn xếp - stack<> queue<>
  • Bảng ánh xạ dữ liệu - map<>
  • ...

7. Exception handling

Exception handling được sử dụng trong các ngôn ngữ lập trình cấp cao, trong C++ cũng được hỗ trợ điều này với mục tiêu chính phân tích và xử lý các trường hợp xảy ra không như mong đợi hoặc đôi khi dùng để bỏ qua lỗi để xử lý được tiếp tục.

Sử dụng tính năng này với C++ không khó vì chỉ cần nắm giữ các keyword:

  • try theo dõi và bắt ngoại lệ.
  • catch nhận và xử lý ngoại lệ.
  • throw tạo ra ngoại lệ khi đạt 1 điều kiện nhất định.

8. C++11 và C++1x

Sau thời kỳ ổn định với C++98, C++11 ra đời để bắt kịp thời đại và là 1 bản cập nhật lớn mở đường cho 1 loạt cập nhật mới như C++14, C++17, ... rất nhiều tính năng mới giúp giải quyết nhiều vấn đề.

  • Move semantics giảm hao phí vì sao chép vùng nhớ của các đối tượng tạm.
  • Lambda expression rút ngắn thời gian khai báo hàm cho các tác vụ nhỏ.
  • auto tối ưu tốc độ gõ code khi không phải khai báo các kiểu dữ liệu dài hoặc phải tốn kém thời gian xem xét kiểu dữ liệu trả về.
  • Smart pointer giải quyết các vấn đề chia sẻ dữ liệu giữa các pointer, hoặc giới hạn việc chia sẻ thông qua: shared_ptr<>unique_ptr<>.

Với C++11 bạn chỉ cần cập nhật 1 số tính năng cần thiết như nêu ở trên, và dần dần tìm hiểu sâu hơn.

9. Multithreading

Các hệ thống hiện đại ngày nay đều được thiết kế theo hướng đa nhân, đa luồng trong cả CPU lẫn GPU. Vì vậy để tận dụng được hết sức mạnh của hệ thống, việc áp dụng xử lý đa luồng là cần thiết. Ngoài ra, với xử lý đa luồng sẽ giúp khắc phục các vấn đề về xử lý bất đồng bộ, tạo cho chương trình hoạt động một cách mượt mà hơn.

Trước khi có sự ra đời của C++ 11, việc xử lý các tác vụ đa luồng yêu cầu phải thao tác trực tiếp trên các API của hệ điều hành thông qua việc sử dụng các hàm như CreateThread() của Windows hoặc folk() của Linux. Tuy nhiên, bất lợi của việc thao tác trực tiếp trên các API này là sự bất đồng bộ trong code khi chạy trên các hệ điều hành khác nhau, song song đó vấn đề mỗi hệ điều hành sử dụng một phương pháp quản lý luồng cũng là một vấn đề phải lưu tâm. Kể từ C++11, thư viện quản lý đa luồng đã được thêm vào giúp việc thao tác tạo và quản lý tương đồng trên các hệ điều hành, giảm thiểu lỗi và các vấn đề tương thích.

Mặc dù có nhiều ưu điểm, việc xử lý đa luồng sẽ phát sinh sự xung đột của các tài nguyên dùng chung như 2 luồng xử lý cùng thao tác trên một vùng nhớ và dẫn đến việc sai khác dữ liệu. Để tránh việc này, các kĩ thuật xử lý xung đột được áp dụng như:

  1. Biến điều kiện kết hợp toán tử atomic - C++11 thư viện <atomic> hoặc <condition_variable>
  2. Mutex - C++11 thư viện <mutex>
  3. Semaphore - C++20 thư viện <counting_semaphore> hoặc <binary_semaphore>
  4. Sử dụng trực tiếp các API của hệ điều hành

Khi sử dụng các phương pháp trên, vấn đề deadlock - các luồng xử lý không thể hoàn tất được - có thể xảy ra, một số nguyên nhân gây deadlock là chờ tài nguyên xoay vòng, luồng xử lý phức tạp, ngốn thời gian … Vì vậy khi thiết kế xử lý đa luồng cần cân nhắc các trường hợp xảy ra deadlock và sắp xếp thứ tự xử các luồng phù hợp.

10. Design Patterns

Trong các kiến trúc phần mềm, design pattern xuất hiện ở mọi nơi và mọi cấp độ. Trường hợp của web có MVC ở cấp độ cao nhất khi bao quát tổng thể của 1 dự án web.

Các design pattern không nhất thiết phải tìm hiểu hết tất cả nhưng bạn có thể bắt đầu với các đề xuất bên dưới.

  • Singleton design pattern.
  • Factory design pattern.
  • Proxy design pattern.
  • Adapter design pattern.

Ngoài design pattern, còn nhiều nguyên tắc để kiến trúc phần mềm có thể dễ dàng bảo trì và mở rộng như SOLID principles.

11. GNU Compiler - Building process & Make file

Trong 1 project C++ thực tế có thể được viết cho nhiều nền tảng khác nhau, do đó cần nắm bắt thêm cấu trúc của 1 project C++, có thể nắm bắt thêm về mặt cấu hình 1 project C++, các option của trình biên dịch, cách make file.

Hiểu được thêm vấn đề này giúp giảm thời gian chuyển đổi giữa các nền tảng và có thể giúp chương trình tối ưu hơn khi sử dụng các công cụ có sẵn.

12. Performance

Hiệu năng không chỉ là cách thức để viết code mà bao gồm nhiều khía cạnh:

  • Cách thức code cho hiệu quả:
    • Sử dụng inline cho giảm thời gian gọi nhưng tăng kích thước của file?
    • Cấp phát tĩnh hay cấp phát động?
    • std::string hay char*?
    • Cấp phát tĩnh đối tượng tại global?
  • Sử dụng design pattern hiệu quả.
  • Cách thức sử dụng các option của trình biên dịch để tối ưu.
  • Tận dụng C++ để kết hợp với các ngôn ngữ lập trình khác.

Sẽ còn rất nhiều vấn đề khi đề cập đến tối ưu như "Tối ưu tốc độ hay bộ nhớ?", "Tối ưu hiệu năng hay tối ưu bảo trì?" và sự suy xét trong việc đánh đổi giữa các lựa chọn này.

Các bạn có thể sử dụng các mục trên để bắt đầu rà soát và bổ sung các khía cạnh C++ còn thiếu để hoàn thiện kiến thức của mình, các kiến thức trên không phải có thể áp dụng hết vào project vì còn phụ thuộc vào các yếu tố:

  • Loại project mà bạn đang làm là gì vì có những project chỉ cần dùng C.
  • Project không chạy trên hệ điều hành, do đó không cần multithreading.

Nếu còn nhiều thắc mắc và cần tư vấn, vui lòng để lại câu hỏi trong phần bình luận.

IO Stream

IO Stream Co., Ltd

30 Trinh Dinh Thao, Hoa Thanh ward, Tan Phu district, Ho Chi Minh city, Vietnam
+84 28 22 00 11 12
developer@iostream.co

383/1 Quang Trung, ward 10, Go Vap district, Ho Chi Minh city
Business license number: 0311563559 issued by the Department of Planning and Investment of Ho Chi Minh City on February 23, 2012

©IO Stream, 2013 - 2024