HỌC HỌC HỌC

Hello hello, mình là Nam, rất hân hạnh được làm quen với các bạn. Lâu rồi không viết bài mới trên Nam .NET, còn ai nhớ tới mình không nhỉ? 🤪

Bài viết cuối cùng trên trang này cũng đã cách đây nửa năm, trong thời gian qua tôi khá bận rộn với công việc, nhà cửa, gia đình, học hành… nhưng lý do quan trọng nhất có lẽ là vì không biết viết gì. Thường thì lúc rảnh tôi hay vào các nhóm sinh viên CNTT, hoặc các nhóm lập trình để tìm hiểu xem xu hướng các bạn làm gì và như thế nào, cũng như hỗ trợ các bạn đang gặp khó khăn trong việc học.

Continue reading “HỌC HỌC HỌC”

PHÂN TÍCH THIẾT KẾ VÀ KIẾN TRÚC HỆ THỐNG (3 LĨNH VỰC YÊU THÍCH CỦA TÔI – phần 3)

Với 2 lĩnh vực yêu thích trước: Hệ điều hành và ngôn ngữ lập trình, tất cả chỉ dừng lại ở mức sở thích mà thôi, những gì tôi đã làm chỉ là các dự án nhỏ, hoặc là một phần nhỏ của các dự án khác. Trong tương lai tôi cũng chưa có ý tưởng gì về chúng xa hơn một đam mê cá nhân, vì thực sự cả 2 đều là những lĩnh vực khó và đòi hỏi một nguồn lực rất lớn.

Continue reading “PHÂN TÍCH THIẾT KẾ VÀ KIẾN TRÚC HỆ THỐNG (3 LĨNH VỰC YÊU THÍCH CỦA TÔI – phần 3)”

NGÔN NGỮ LẬP TRÌNH VÀ TRÌNH BIÊN DỊCH (3 LĨNH VỰC YÊU THÍCH CỦA TÔI – phần 2)

Trên thế giới này có bao nhiêu ngôn ngữ lập trình? Chịu, không ai biết được. Chỉ cần kể ra những cái tên nổi tiếng đã có rất nhiều: C, C++, Fortran, Pascal, JavaScript, Java, Python, Perl, Basic, C#, F#, Dart, Go… hay các ngôn ngữ chuyên dụng như SQL, VBA, Powershell script…Vậy tại sao tôi lại thích học về ngôn ngữ lập trình? Câu trả lời rất đơn giản: Vì tôi thích! Khi còn đi học, cũng như những sinh viên hay mơ mộng khác, tôi cũng có mơ ước một ngày nào đó sẽ tự phát minh ra một ngôn ngữ mới. Và thật sự tôi cũng đã từng tạo ra một vài trình biên dịch nhỏ trong quá trình học và làm việc: một trình dịch giúp hỗ trợ syntax highlighting khi khách hàng viết các SMS template (các SMS này sẽ có thể chứa các thông tin về đơn hàng và được gửi đến cho các tài xế), một trình dịch khác cũng phục vụ highlighting cho 1 Java IDE (kiểu như VS code – IDE này là một pet project).

Continue reading “NGÔN NGỮ LẬP TRÌNH VÀ TRÌNH BIÊN DỊCH (3 LĨNH VỰC YÊU THÍCH CỦA TÔI – phần 2)”

3 LĨNH VỰC YÊU THÍCH CỦA TÔI – phần 1

Công nghệ thông tin là một lĩnh vực rất rộng, không ai có thể giỏi tất cả, vì vậy việc chọn cho mình một ngôn ngữ, nền tảng hay chuyên ngành riêng nào đó rất quan trọng.

Câu hỏi thường gặp nhất sẽ là: Tôi nên học gì để sau này có việc làm? Thật sự công việc trong ngành này rất nhiều, và sẽ càng ngày càng nhiều, nhất là trong bối cảnh các xu hướng làm việc từ xa, dữ liệu lớn, AI, IoT… đang trở nên phổ biến hơn bao giờ hết. Nhưng tôi chắc chắn bạn chưa bao giờ tìm được một đáp án thỏa mãn, bởi đơn giản chỉ bạn mới có thể trả lời chính xác mà thôi.

Câu trả lời của tôi luôn là: Bạn hãy học những gì bạn thích nhất!

Continue reading “3 LĨNH VỰC YÊU THÍCH CỦA TÔI – phần 1”

GIẢI THÍCH: Vấn đề nằm ở CPU cache

👉 Khi nằm trong bộ nhớ, các mảng nhiều chiều sẽ được diễn dịch thành một mảng 1 chiều (vì bộ nhớ về cơ bản cũng chỉ là mảng 1 chiều). Mỗi dòng sẽ được sắp xếp liên tục theo thứ tự. Mỗi khi cần truy xuất đến 1 ô nào đó có địa chỉ m[dòng, cột], trình biên dịch sẽ biến đổi thành m[dòng * chiều rộng mảng + cột] (xem hình minh họa).

👉 Như vậy, nếu ta đi chuyển theo dòng->cột (tương ứng với calculate_sum(sum, 1) trong https://github.com/…/clanc…/blob/master/CachingTests.cpp), thứ tự truy xuất trong bộ nhớ sẽ được tăng dần, trong khi đó, nếu ta di chuyển theo cột->dòng, thứ tự truy xuất theo hình minh họa sẽ là 0, 4, 8, 1, 5…

👉 Bộ nhớ cache trong CPU được tổ chức theo từng lance (không biết dịch ra thế nào, trong tiếng Việt ta vẫn dùng từ lance để chỉ các phần đường phân cách nhau). Mỗi lance có kích thước 64 byte, mỗi khi nạp từ RAM vào cache, hay từ cache vào RAM nó sẽ luôn làm việc với từng lance như vậy. Do đó khi đọc vào 1 byte, tất cả các byte lân cận trong cùng lance sẽ nằm sẵn ngay trong cache, khi bạn đọc đến byte kế tiếp bạn chỉ cần lấy nó ra từ cache (cache hit). Tốc độ của cache lại nhanh hơn RAM rất nhiều, người ta tính toán rằng cache L1 trong CPU có tốc độ nhanh hơn vài chục tới cả trăm lần so với truy xuất từ RAM.

👉 Kết quả là việc đọc/ghi dữ liệu tuần tự sẽ cho tốc độ tốt hơn nhiều so với truy xuất ngẫu nhiên. Điều này cũng tương tự như khi bạn đọc dữ liệu từ ổ SSD, vốn không có các cơ cấu cơ học và không có thời gian di chuyển đầu đọc như HDD, tuy nhiên khi copy 1 file lớn vẫn nhanh hơn nhiều so với copy nhiều file nhỏ. Đó cũng là do khi đọc/ghi tuần tự thì xác suất cache hit sẽ lớn hơn nhiều so với cache miss.❗️Khi làm việc với các ứng dụng lớn, việc tổ chức cách lưu trữ dữ liệu rất quan trọng!

VÌ SAO DUYỆT MẢNG THEO DÒNG LẠI NHANH HƠN THEO CỘT?

Mình vừa viết một chương trình nhỏ, chỉ để tính tổng các ô trong một ma trận, tuy nhiên khi thử duyệt theo dòng thì luôn thấy nhanh hơn cột, mảng càng lớn tốc độ càng khác biệt.Các bạn có thể tải về chương trình tại ( https://github.com/namdotnet/clancetest) và chạy thử xem có đúng không, và mất bao nhiêu tick mỗi bước, laptop mình đang dùng chạy Xeon mất hơn 600 ticks cho bước 1.

Nếu nhiều người ủng hộ thì mình sẽ giải thích lý do tại sao 😉(ghi chú là trong ví dụ này mình gọi dòng trước cột sau nhé int m[ROWS][COLS]).

TỪ NGÔN NGỮ LẬP TRÌNH ĐẾN MÃ MÁY (phần 2)

Sau khi đã hoàn thành tiền xử lý, chúng ta sẽ sang bước thứ hai: Biên dịch.

Về cơ bản quá trình biên dịch nhận đầu vào là file mã nguồn, phân tích nó và xuất ra file nhị phân chứa mã thực thi. Quá trình này sẽ chia làm 3 bước chính:

👉 Phân tích từ vựng (lexical analysis)Trình biên dịch sẽ đọc file mã nguồn, từng ký tự một, sau đó phân tích các ký tự rời rạc đó thành các từ vựng trong bộ từ vựng của ngôn ngữ tương ứng.

Xét ví dụ sau:

int x = myfunc(x) * 10

Ví dụ trên sẽ được phân tích thành các từ vựng (ta có thể dùng từ tiếng Anh là token): int, x, =, myfunc, (, x, ), *, 10.Trình phân tích từ vựng sử dụng các ký tự phân tách (khoảng trắng, tab, xuống dòng, dấu chấm phẩy… tùy ngôn ngữ) để tìm ra các từ vựng, nó cũng biết rằng chữ n và t nằm sau i phải được kết hợp thành keyword int, ký tự 1 và 0 phải được kết hợp thành một nhóm là 10 – và đây là một số nguyên, tương tự cho các token còn lại.

Continue reading “TỪ NGÔN NGỮ LẬP TRÌNH ĐẾN MÃ MÁY (phần 2)”

TỪ NGÔN NGỮ LẬP TRÌNH ĐẾN MÃ MÁY (phần 1 – preprocessing)

Bạn đã biết C++ chưa? Đã học C#, Java, JavaScript, Python?Nghe nói Assembly khó lắm? Nếu Assembly khó thì mã máy thế nào?

Trong bài viết này tôi sẽ cố gắng mô tả quá trình từ một chương trình viết bằng ngôn ngữ bậc cao được dịch và thực thi như thế nào, hi vọng sau bài viết này các bạn sẽ có một cái nhìn tổng quan, hiểu được cơ bản và có thể tự mình giải quyết được các trục trặc thường gặp.Trong loạt bài này tôi sẽ chủ yếu minh họa bằng C, vì đây là ngôn ngữ có đầy đủ “đồ chơi” nhất, cũng như gần với các ngôn ngữ cấp thấp nhất.

❓Trình biên dịch làm thế nào để biến chương trình của bạn thành mã máy?

Continue reading “TỪ NGÔN NGỮ LẬP TRÌNH ĐẾN MÃ MÁY (phần 1 – preprocessing)”

Tại sao chúng ta phải vẽ ra các sơ đồ khi thiết kế ứng dụng?

Các sơ đồ (class, sequence, E-R, database…) được vẽ ra để:

– Trực quan hóa: giúp người thiết kế dễ dàng nhìn thấy các thực thể, các mối quan hệ, tìm ra các vấn đề có thể xảy ra và xây dựng bước thiết kế tiếp theo.

– Xây dựng tài liệu giúp tra cứu lại sau này, giúp các thành viên mới tham gia vào dự án có thể hiểu được.- Trao đổi thông tin giữa các thành viên trong dự án khi thiết kế.

ℹ️ Mục đích của vẽ diagram, kể cả các UML diagram là để giúp thiết kế/lập tài liệu dễ dàng hơn, không phải là một phương pháp thiết kế.

Continue reading “Tại sao chúng ta phải vẽ ra các sơ đồ khi thiết kế ứng dụng?”

EVENT LOOP TRONG JAVASCRIPT

Sau khi dạo chơi hết C, C++, Java giờ page .NET xin giới thiệu một bài viết mới về JavaScript :v

❗️ Mô hình xử lý [đồng thời] trong JS có phần khác so với các ngôn ngữ truyền thống như C hay Java, trong đó mỗi chương trình JS (một trang web, web worker hay cross origin iframe) sẽ chỉ chạy trên một thread.

Continue reading “EVENT LOOP TRONG JAVASCRIPT”