Chuyển đến nội dung chính

CS-101 How does a Program Run?

 Chương trình máy tính "chạy" như thế nào?

Là một Software Engineer - người thiết kế và phát triển chương trình phần mềm đòi hỏi bạn phải biết một phần mềm hoạt động một cách cơ bản như thế nào.

Chúng ta sẽ lần lượt qua các giai đoạn mà một phần mềm (ví dụ cụ thể là một chương trình máy tính) hoạt động, từ lúc khởi chạy đến khi kết thúc.

Làm sao để khởi chạy chương trình?

Để khởi chạy chương trình bạn cần mở file có extension là .exe trên Windows hoặc .app trên macOS.

Ngay sau khi file được mở, chương trình sẽ được khởi chạy trên máy tính và bạn có thể thao tác với nó.

Vậy file có đuôi .exe/.app chứa thông tin gì, tại sao nó lại khởi chạy được chương trình?

    File .exe/.app is mostly the bytes of machine code instructions.

Nghĩa là nó chứa các lệnh chỉ dẫn máy tính (instruction) thực thi dưới dạng byte. Thường thì một lệnh chỉ dẫn sẽ gồm 4 bytes.

Như vậy có thể hiểu một chương trình máy tính là tập hợp các câu lệnh thực hiện một tác vụ cụ thể khi được máy tính thực thi.

Dữ liệu của chương trình được lưu ở đâu?

Bạn thức cả đêm để viết một bài báo cáo vài chục trang trên Microsoft Word mà chưa nhấn Save, đột nhiên cúp điện, làm PC của bạn tắt. Sáng hôm sau khi có điện, bạn mở Microsoft Word lên, toàn bộ bài báo cáo tối qua đã biến mất 😭. TẠI SAO????

Toàn bộ những lệnh chỉ dẫn trong file .exe/.app, và các dữ liệu chương trình thao tác sẽ được lưu trữ vào bộ nhớ RAM.

    The RAM area holds the program's code and data it manipulates.

Về chi tiết thì mình sẽ viết ở một bài post khác, các bạn có thể research với từ khóa call stack, heap để hiểu sâu hơn về cách các dòng lệnh và dữ liệu được lưu trong RAM.

RAM là bộ nhớ tạm thời vậy nên dữ liệu sẽ bị mất đi khi máy tính bị mất điện.
Thao tác Save trên các chương trình ví dụ như Microsoft Word dùng để lưu dữ liệu xuống DISK dưới dạng file.
Ngoài ra để tránh rủi ro khi bạn quên Save hoặc phải nhấn Save quá nhiều lần thì các chương trình máy tính hiện nay đều có tính năng Auto Save (tự động lưu khi dữ liệu bị thay đổi).

RAM chỉ lưu những lệnh chỉ dẫn, vậy ai thực thi những chỉ dẫn này?

Đó chính là bộ não của máy tính - CPU
CPU "theo dõi" các chỉ dẫn trên RAM và thực thi chúng.
    CPU fetch-execute circle runs through the instruction series.

Kết thúc chương trình

Khi chương trình kết thúc, toàn bộ dữ liệu của chương trình đó trên RAM sẽ được giải phóng.

Ai quản lý toàn bộ hoạt động của các chương trình máy tình, từ lúc khởi chạy đến lúc kết thúc?

Đó chính là Hệ điều hành (Operating System).
    OS is a supervisory program begins running when the computer first starts up.
    Hệ điều hành cũng là một chương trình máy tính nhưng đặc biệt dùng để điều hành, quản lý toàn bộ tất cả thành phần (bao gồm cả phần cứng và phần mềm) của thiết bị điện tử.
Có vai trò trung gian trong việc giao tiếp giữa người sử dụng và thiết bị.

Lỗi Not Responding

Khi bạn mở quá nhiều tab trên Chrome đột nhiên Chrome đứng im, hiện lỗi Not Responding khiến bạn không thể thao tác gì được nữa.
Lúc này bạn đợi một lúc, Chrome (có thể) sẽ hoạt động lại bình thường, hoặc để nhanh và hiệu quả hơn thì bạn nên tắt Chrome rồi mở lại, thậm chí Restart lại máy tính.

Tại sao lỗi này lại xuất hiện?

Khi các chương trình khởi động, hệ điều hành sẽ cung cấp vùng nhớ cho từng chương trình trên RAM.
RAM là bộ nhớ có giới hạn nên khi không còn đủ vùng nhớ nữa thì chương trình sẽ rơi vào trạng thái tạm ngừng hoạt động, lúc này lỗi Not Responding sẽ xuất hiện, hệ điều hành sẽ cố gắng dọn dẹp và cấp phát lại vùng nhớ để chương trình tiếp tục hoạt động.
Nguyên nhân tiếp theo đó là do lỗi của hệ điều hành, hệ điều hành trên máy tính cũng là một chương trình, nên việc nó gặp lỗi (bug) khi cấp phát, chia sẻ vùng nhớ giữa các chương trình với nhau là chuyện hoàn toàn có thể xảy ra.

Cách khắc phục

Cách tạm thời: tắt chương trình rồi mở lại, hoặc Restart lại máy tính, mục đích để dọn dẹp bộ nhớ trên RAM.
Cách dài hạn: 
  • Nâng cấp RAM để có nhiều dung lượng bộ nhớ hơn (recommended).
  • Đổi sang chương trình có chức năng tương tự nhưng sử dụng ít bộ nhớ RAM hơn (ví dụ bạn có thể đổi trình duyệt từ Chrome sang Microsoft Edge chẳng hạn 😂).
  • Đổi sang hệ điều hành mới (ví dụ từ Windows sang macOS).

Tổng kết

Qua bài viết này bạn đã hiểu được cách một chương trình máy tính hoạt động như thế nào. Mình xin tóm tắt lại trình tự như sau:
1. Launch .exe/.app file.
2. The instruction bytes are copied from storage to RAM.
3. The CPU is directed to start running at the first instruction.
4. Now the program is running, data it manipulates is stored in RAM.
5. Stop program ➡ clean up RAM.
Tất cả các hoạt động trên đều do hệ điều hành quản lý.

Hy vọng bạn có được thêm kiến thức mới.
Keep learning 💪

Nhận xét

Bài đăng phổ biến từ blog này

Effective Java 01 - Consider static factory methods instead of constructors

Ở bài viết này, chúng ta sẽ bàn về cách để tạo Object trong Java. Để tạo mới một Object trong Java thì cách truyền thống là provide một public constructor và sử dụng keyword new ở client. Có một cách khác mà chúng ta nên biết và consider để sử dụng thay cho cách truyền thống đó là provide static factory methods . Vậy ưu điểm và nhược điểm của static factory methods là gì, chúng ta sẽ cùng tìm hiểu trong bài viết này. Cách truyền thống: Provide a public constructor Ví dụ: Class Student.java public class Student { private long id ; private String name ; public Student ( long id , String name ) { this . id = id ; this . name = name ; } } Client có thể tạo instance bằng cách sử dụng new keyword: Student student = new Student ( 1 , "Nguyễn Văn A" ); Sử dụng Static Factory Methods Ví dụ: Class Student.java public class Student { private long id ; private String name ; private Student ( long id , Strin...

Effective Java 02 - Consider a builder when faced with many constructor parameters

 Khi một Object có thể được tạo từ nhiều attributes khác nhau thì chúng ta nên consider sử dụng Builder Pattern thay cho Static factories hoặc Constructors . Ví dụ sử dụng Builder Pattern: // Builder Pattern public class NutritionFacts { private final int servingSize ; private final int servings ; private final int calories ; private final int fat ; private final int sodium ; private final int carbohydrate ; public static class Builder { // Required parameters private final int servingSize ; private final int servings ; // Optional parameters - initialized to default values private int calories = 0 ; private int fat = 0 ; private int sodium = 0 ; private int carbohydrate = 0 ; public Builder ( int servingSize , int servings ) { this . servingSize = servingSize ; this . servings = servings ; } public Builder calories ( int val ) { calories = val ; retu...