Bắt đầu với Node JS - V8 và NodeJS ??? (Phần 1)

1) Bộ vi xử lý , mã máy và C++.




Có thể bạn tự hỏi "Chờ đã ... có gì đó sai ở đây , tôi đọc bài viết này để tìm hiểu về NodeJS và nó được viết về JS mà  nhưng bạn hãy tin tôi những kiến thức trên chính là nền tảng cốt lõi để hiểu được bản chất của NodeJS .

a) Bộ vi xử lý : Bạn nghe khái niệm này có vẻ quen quen , thật ra mọi hành động bạn thao tác trên máy tính , bạn đọc bài viết này , bạn nghe nhạc .... đó là do bộ vi xử lý trong máy tính của bạn xử lý các tác vụ này , bạn không cần tìm hiểu quá sâu về bộ vi xử lý , bạn có thể hiểu nó như một cái máy rất nhỏ.


- Làm sao để bộ vi xử lý có thể thực hiện một tác vụ ?

- Để hiểu được vấn đề này bạn cần hiểu 1 vài lưu ý quan trọng sau.

+ Để bộ vi xử lý hoạt động chúng ta cần cung cấp cho nó những hướng dẫn hay còn gọi là lệnh , hướng dẫn được viết bằng mã máy để bộ VSL hiểu được (machine code).

+ Không phải tất cả các bộ VSL đều có hướng dẫn giống nhau cho 1 hành động. (tức nó không hiểu  chung 1 loại machine code) đây chính là lý do vì sao có phần mềm chạy được trên WINDOW nhưng ko chạy được trên LINUX.

+ Chúng ta bắt buộc phải cung cấp hướng dẫn (nói lại lần thứ 2 : hướng dẫn này được viết bằng mã máy machinecode) mà bộ VSL hiểu được  để chạy các chương trình.


+ Dưới đây là một vài ngôn ngữ mà bộ VSL hiểu được.(các hướng dẫn được viết bằng những loại ngôn ngữ này) và những ngôn ngữ này được gọi chung là mã máy (machine code)


+ Nói một cách rõ ràng về machineCode thì chúng ta cần hiểu như sau : 

- Đây là ngôn ngữ lập trình mà bộ vi xử lý giao tiếp và điểu khiển các thành phần trong máy tính để chương trình hoạt động (ví dụ như cấp phép , giải phóng ram ....)

- Mọi chương trình khi chạy trên máy tính đều phải dịch sang mã máy mới chạy được (điều này cũng dễ hiểu thôi). Ví dụ nhưng khi bạn chạy 1 trình phát nhạc viết bằng Java thì phải dịch Java sang mã máy để bộ VSL hiểu được đã.

+ Tại sao không viết trực tiếp chương trình bằng mã máy  ? => Vì nó quá phức tạp để người bình thường hiểu được.

Dưới đây là ví dụ về một vài dòng mã máy (đây chỉ là một trong nhiều loại mã máy mà mình đã nêu ở trên) , mỗi bộ VSL chỉ hiểu được một vài loại mã máy nhất định.



+ Học cách viết mã máy rất khó do đó chúng ta phải tạo ra những ngôn ngữ thân thiện với dev hơn để nó dễ học , dễ viết và chúng ta chúng là các  ngôn ngữ bậc cao. tất nhiên là các ngôn ngữ bậc cao phải được biên dịch ra mã máy nếu nó muốn chạy. 

- Dưới đây là một bảng xếp hạng (các ngôn ngữ dưới đây chỉ là ví dụ để minh họa sự gần gũi của nó đối với mã máy) ngôn ngũ xếp hạng càng cao thì nó càng khác biệt so với mã máy và đương nhiên là nó mất nhiều thời gian để biên dịch hơn 
=> Đó chính là lý do nhiều người nói C/C++ nhanh và mạnh mẽ.


+ Như bạn có thể thấy Javascript là ngôn ngữ bậc cao , nó khác rất xa với mã máy.

+ Rõ ràng là các chương trình viết bằng JS nếu muốn chạy cần một bộ chuyển đổi để bộ VSL hiểu được.

+ Từ nãy đến giờ bỏ rơi thằng em NodeJS , có một điểm hay nhầm lẫn của một newbie nhưng mìn hay mắc phải khi đọc tài liệu trên mạng đó là một câu nói là : Node is written in C++ tức là NodeJS viết bằng C++ ..wtf ??  éo hiểu luôn , tôi viết chương trình NodeJS bằng JS mà C++ liên quan cc gì ở đây. ??? Không phải đâu bạn tôi ơi ... Bạn viết chương trình NodeJS bằng JS nhưng bản thân thằng Node (mã nguồn của Node) phần lớn lại viết bằng  C++.

+ V8 là công cụ dịch mã  JS sang mã máy viết bằng C++ .

+ Trong Node không chỉ có mỗi V8 nó còn rất nhiều thành phần khác được viết bằng JS , Node là một Javscript Runtime xây dựng dựa trên V8.

+ V8 là một Javascript engines vậy js engines là gì ?????


2) Javascript Aside : Javascript Engines và Đặc tả ECMAScript.

+ Javascript Engines là một trình biên dịch mã JS sang mã máy và nó phải tuân theo chuẩn ECMA.
V8 là một trong rất nhiều JS Engines và nó tuân theo chuẩn ECMA

+ ECMAScript là tiêu chuẩn mà JS phải dựa trên nhưng nó là cái quái gì ???
=> Khi JS được viết ra mục đích ban đầu của nó chỉ là phục vụ phía Client vì nó là một ngôn ngữ kịch bản nên các công ty phát triển trình duyệt như Microsoft , Netscape ... họ sẽ tự phát trên công cụ dịch JS sang mã máy của riêng mình , tất nhiên điều này làm phân mảnh của các hãng công nghệ khiến họ không tận dụng được thành quả nghiên cứu mà các hãng khác đã nghiên cứu ra rồi hơn nữa khi một developer tạo ra một trang web họ phải viết trang web đó cho từng trình duyệt khác nhau.

+ Lúc này ECMA ra đời : tổ chức này mô tả chính xác cách mà mã JS được biên dịch sang mã máy một cách thống nhất giữa rất nhiều hãng công nghê hay nói dễ  hiểu hơn nó mô tả chính xác kết quả của một câu lệnh , ngôn ngữ nên hoạt động như thế nào? một kịch bản cốt lõi .Ví dụ như là console.log thì in ra màn hình console...

+ V8 là một trong rất nhiều Javascript Engines được tạo ra, V8 phải tuân theo chuẩn của ECMA , ECMA chính xác hơn thì nó mô tả kết quả chính xác của một dòng lệnh JS khi bạn chạy , hay nó là cách mà JS nên hoạt động.

Bạn có thể hiểu đơn giản như thế này .V8 đọc  code của bạn , nó hiểu rằng bạn muốn thực thi một hành động nào đó (để nhận diện các hành động thì code của bạn phải tuân thủ theo chuẩn của ECMA để V8 hiểu bạn muốn làm gì ?) khi nó đã hiểu bạn muốn làm gì thì nó sẽ thực hiện hành động đó bằng C++..Điều này về bản chất có thể cho phép JS làm bất cứ điều gì mà C++ có thể làm đc.


3) Đi sâu và V8

Khi mình mới học NodeJS , hiểu được V8 là gì , nó có ý nghĩa thế nào , nó  hoạt động ra sao là điều khó khăn nhất đối với mình và mình nghĩ đối với hầu hết các bạn newbie như mình đều gặp phải vấn đề này.

- Google V8 Engines là một mã nguồn mở nên nó public với tất cả mọi người , thậm chí thay đổi , mở rộng tùy theo mục đích của người dùng nó như mình đã giải thích phần trên V8 được viết bằng C++.

- Để tìm hiểu sâu hơn vào V8 bạn có thể vào trang v8.dev/


- Mình kém TA nên dịch đại ý như này :
 + Nó dịch code JS sang mã máy
 + V8 là một JSE mã nguồn mở của google.
 + Được viết bằng C++.
 + Nó tuân thủ theo quy tắc ECMA
 + Nó có thể hoạt động trên các nền tảng LINUX , WINDOW , MAC chạy trên các bộ vi xử lý x64 , IA-32 , ARM hoặc MIPPS.
 + Nó có thể chạy độc lập hoặc được nhúng vào bất kì chương trình C++ nào.

- Để truy cập mã nguồn của V8 bạn có thể vào https://github.com/v8/v8

Tóm tắt : Bạn viết ra code JS , khối code này sẽ được truyền cho V8 (được viết bằng C++) và V8 bằng một cách nào đó tạo ra cho bạn mã máy từ đó tạo ra hướng dẫn để bộ VXL hoạt động.



- Chúng ta có thể thêm tính năng mới nó V8 không ? bằng cách nào ? 


- Chúng ta đều biết V8 là một JSE để dịch code JS sang machine code và nó được viết bằng C++

- Điều này cực kì có ý nghĩa vì JS là một ngôn ngữ bậc cao nó rất khác biệt so với mã máy , các tác vụ đòi hỏi tính tương tác với hệ thống cao như đọc ghi file , giải phóng ram viết bằng mã JS gần như rất khó nhưng đối vs C++ lại rất dễ vì nó rất gần gũi với mã máy. Do đó nếu chúng ta muốn thêm bất kì một ứng dụng mới nào cho V8 chúng ta chỉ cần viết nó bằng mã C++ và nhúng V8 và trong ứng đó. 

- Bạn có thể tự config V8 chạy như thế nào , biên dịch như thế nào theo cách của bạn.




NodeJS  là gì ?

NodeJS là một javascript runtime xây dựng dựa trên V8 (hầu hết Node được viết bằng C++ , một phần nhỏ được viết bằng JS)

=> Có thể hiểu đơn giản runtime là một môi trường mà javascript có thể chạy bên trong nó, có những runtime khác nhau như Node hay Chrome và tất nhiên nếu muốn chạy code JS thì runtime JSE(V8) được nhúng vào runtime và trong runtime không chỉ có một mình V8 còn rất nhiều thứ khác nữa , hoặc bạn có thể hiểu rằng runtime như một container lớn chứa nhiều container con, V8 cũng là một container trong số đó, những container này liên kết để làm việc cùng nhau tạo nên Runtime, hoặc một ví dụ rất hay nữa về runtime mình đọc được đó là bạn hãy tưởng tượng.
- Tệp JS bạn muốn thực thi => Như một bản nhạc
- V8 => Như một nghệ sĩ 
- Runtime => Là một nơi cung cấp cho người nghệ sĩ (V8) những nhạc cụ để chơi bản nhạc (tệp JS).

=> Khi javascript được chạy trong Runtime , runtime sẽ cung cấp cho JS khả năng xử lý các tác vụ mà JS bản thân nó không thể xử lý được , ví dụ như trong Browser thì thao tác với DOM, FETCH...
hay trong Node thì ReadFile, WriteFile... . Nói rõ hơn về quá trình này thì khi tệp JS được đẩy vào trong V8 ban đầu nó sẽ được thực thi từng dòng (thông dịch), khi V8 chạy đến những tác vụ nó không xử lý được, V8 sẽ gọi những API mà Node hay Chrome cung cấp để xử lý các tác vụ này (Bạn nhớ rằng Runtime là một Container lớn và những container này có thể liên kết với nhau để làm việc)

=> Ví dụ trong Node khi gặp một tác vụ đọc ghi file chẳng hạn thì V8 sẽ nhờ LibUv xử lý,LibUv là một module được viết bằng C++ , bởi vì JS không thiết kế ra để tương tác sâu vào hệ thống nên nó không đọc ghi file được hay nói đúng hơn là V8 không đọc ghi file được. nhưng C++ thì có.
 Khi LibUv nhận được yêu cầu từ V8 nó sẽ xử lý quá trình này như vậy quá trình này bản thân chúng ta viết code JS ra để xử lý nhưng về mặt bản chất quá trình này là những dòng code C++ được thực thi.
 

Nhận xét

Bài đăng phổ biến