Khi nào bạn bắt đầu có thể học về thiết kế?

Có một số bạn nhắn tin hỏi về công việc thiết kế, cũng như cần chuẩn bị gì để học, trong bài này tôi sẽ gom chung một số câu hỏi thường gặp nhất dành cho các bạn quan tâm.

👉 Khi nào tôi có thể bắt đầu học về phân tích thiết kế: Để bắt đầu học, bạn cần tương đối thành thạo về lập trình, đặc biệt lập trình hướng đối tượng (OOP). Hãy nhớ OOP là một cách tư duy về tổ chức chương trình, chứ không chỉ là một phương thức lập trình. Bạn thậm chí có thể bắt đầu học về phân tích thiết kế từ năm 1, năm 2 đại học, tùy vào khả năng của bạn lúc đó đến đâu.

👉 Công việc của nhà thiết kế phần mềm là gì? Một nhà thiết kế thông thường vẫn là một developer, hàng ngày anh ta vẫn phải code, test, debug… Có lẽ hiếm có nhà thiết kế nào chỉ làm mỗi công việc thiết kế, vì 2 lẽ:- Công việc thiết kế thường không chiếm nhiều thời gian so với các phần việc khác, vẽ ra một component, cùng các class bên trong nhanh hơn nhiều so với code/test/debug/release/doc nó.- Các phần việc còn lại (code/test/debug/release/doc) cũng thực sự phức tạp, thiếu hiểu biết về chúng sẽ dẫn đến việc thiết kế ra các mô hình không thực tế, cũng như không thấy được những khó khăn có thể gặp phải. Vậy nên bạn vẫn phải làm công việc của một developer để cập nhật các kỹ năng trên. Thật sự muốn trở thành một nhà thiết kế giỏi, bạn cũng phải là một nhà phát triển giỏi, nhưng không nhất thiết phải chờ đến khi lập trình giỏi thì mới bắt đầu học thiết kế – bạn hoàn toàn có thể học song song cả hai.

Continue reading “Khi nào bạn bắt đầu có thể học về thiết kế?”

LÀM QUEN VỚI PHÂN TÍCH THIẾT KẾ

Một trong những câu hỏi tôi luôn suy nghĩ trong đầu khi bắt đầu bước vào ngành phần mềm là làm thế nào để từ một bài toán thực tế ta có thiết kế ra được các thành phần bên trong một cách đúng đắn: DLL, class, property… Tôi tin rằng các bạn cũng có cùng câu hỏi như vậy, có một kiến thức tốt về thiết kế không chỉ giúp cho công việc hiện tại mà còn mở ra một chân trời mới trong con đường sự nghiệp của bạn.Loạt bài này sẽ giúp bạn có được những kiến thức vững chắc về thiết kế phần mềm, và vì có khá nhiều vấn đề liên quan đến thiết kế nên tôi sẽ viết ra thành nhiều bài theo thứ tự, các bạn chịu khó theo dõi nhé.

Trước khi bắt đầu, ta cần thống nhất với nhau vài điều:

– Kiến thức về OOP là bắt buộc, các phương pháp thiết kế ở đây đều yêu cầu một nền tảng tốt về OOP ❗️.

– Tôi sẽ không viết riêng cho một nền tảng hay ngôn ngữ nào, nhưng sẽ tập trung vào Java và .NET, cùng các ngôn ngữ là Java và C#. Đây là hai trong những nền tảng phổ biến và tốt nhất, đặc biệt cho việc xây dựng các ứng dụng lớn.

– UML: Bạn không cần biết trước về UML, nhưng nếu có kiến thức về nó sẽ rất tốt, đôi khi tôi có thể dùng nó để mô tả.

Continue reading “LÀM QUEN VỚI PHÂN TÍCH THIẾT KẾ”

VIRTUAL ABSTRACT CLASS VÀ INTERFACE

Một trong những câu hỏi thường gặp nhất khi học OOP là: (Virtual) abstract class và Interface khác nhau chỗ nào? Và khi nào sử dụng cái nào?

ℹ️ Câu trả lời đơn giản nhất là: Nếu ngôn ngữ của bạn có hỗ trợ interface thì hãy dùng nó, đừng nghĩ gì về abstract class nữa.Để hiểu hơn về 2 thứ này, ta cần hiểu một chút về trừu tượng trong (abstraction) OOP.

Continue reading “VIRTUAL ABSTRACT CLASS VÀ INTERFACE”

BÀN VỀ FUNCTIONAL PROGRAMMING VÀ OOP PROGRAMMING – bài 2

Vậy là chúng ta đã biết về cả OOP và FP, giờ là câu hỏi quan trọng nhất: Tôi nên đi theo con đường nào?

Thật sự khi viết bài này (cả bài phần 1), tôi không có ý định chỉ ra OOP hay FP tốt hơn, và chọn con đường nào hay hơn. Chính tôi cũng không biết nếu chọn FP thuần túy thì bạn sẽ làm gì ngoài các ứng dụng chuyên về phân tích và xử lý số liệu, mà tôi tin là con số này sẽ rất ít so với phần còn lại.

👉 Thực chất, FP và OOP là hai phương thức tư duy về cách tổ chức các thành phần bên trong ứng dụng. FP cho phép đơn giản hóa việc xử lý các luồng dữ liệu, chia bài toán lớn thành các bài toán con giúp mô hình tổng thể trở nên đơn giản hơn. Nhờ vậy việc viết ra (implement) các đoạn code sử dụng FP trở nên dễ hiểu và ngắn gọn hơn. Ngược lại, OOP phát triển dựa trên các khái niệm từ thế giới thực, và có thể nói OOP khó hiểu và phức tạp hơn FP rất nhiều. Vấn đề là, hầu hết các bài toán ta cần xử lý đều là các bài toán từ thực tế, với các đầu vào, quan hệ, trạng thái cũng từ thực tế, đặc biệt nhìn từ góc độ phân tích, thiết kế và xây dựng kiến trúc hệ thống. Và cũng vì vậy, nếu không có kiến thức về OOP, bạn sẽ khó có thể thiết kế ra các hệ thống phức tạp như trên.

Khi xưa lúc chưa có OOP, người ta vẫn có thể viết ra phần mềm, nhưng thật sự các phần mềm khi đó về quy mô, yêu cầu còn rất đơn giản so với hiện tại. Cũng như các mô hình phát triển ứng dụng kiểu waterfall trước đây vẫn giúp tạo ta các ứng dụng hữu ích, những với các ứng dụng lớn hiện tại, áp dụng mô hình này gần như không khả thi.

Nhìn vào các ngôn ngữ phổ biến nhất hiện tại, ta sẽ thấy không có ngôn ngữ nào là OOP only, hay FP only, mà hầu hết sẽ hỗ trợ cả hai: C#, VB, Java, JS… tất cả đều có OOP và cả FP, những ngôn ngữ vốn thuần túy OOP như C# và Java giờ cũng đều có lambda, JS vốn khi ra đời chỉ là một ngôn ngữ cực kỳ đơn giản, giờ cũng hỗ trợ cả OOP lẫn FP. Nếu nói là chỉ theo OOP hay FP, vậy bạn đang sử dụng ngôn ngữ nào?

👉 Vậy cuối cùng, tôi nên theo con đường nào?Tôi nghĩ đây là một câu hỏi thừa, nếu muốn trở thành một người lập trình chuyên nghiệp, chẳng có lý do gì bạn không thành thạo cả hai. Một người thợ chặt cây nên biết dùng cả cưa và rìu, đừng tự đặt ra câu hỏi tôi nên thành thạo cái nào, vừa mất thời gian vừa tự hạn chế khả năng của mình.FP trong các ngôn ngữ hiện tại giúp bạn viết code rất nhanh và hiệu quả, nếu bây giờ bắt tôi viết C# mà không sử dụng lambda, chắc tôi sẽ thấy chán khi viết các đoạn lệnh tìm kiếm, sắp xếp dài dòng. Còn OOP, với nhiều ưu điểm đã nói đến trong các bài trước, sẽ giúp bạn thiết kế ra các chương trình hiệu quả. Cả FP và OOP đều có những ưu điểm riêng, bạn hãy cố gắng thành thạo cả hai và sử dụng chúng đúng chỗ.

👉 Nên nhớ, OOP là cả một phương pháp thiết kế, nếu đọc qua các design parttern bạn sẽ thấy tất cả đều dựa trên OOP – tôi sẽ vô cùng ngạc nhiên nếu bạn đặt mục tiêu sau này trở thành một software designer, hay một software architecturer, nhưng lại không có ý định tìm hiểu sâu về OOP.

GIỚI THIỆU VỀ JAVA

Bài này được viết với mục đích giới thiệu về Java, một trong những nền tảng và ngôn ngữ phổ biến nhất.

Cái tên Java chỉ đến 3 phần khác nhau: ngôn ngữ Java (Java language), Java runtime và các thư viện Java. Gom chung cả 3 cái lại, ta gọi nó là Java platform.

👉 Ngôn ngữ Java được tạo ra với cú pháp tương tự C/C++/C#, những người đã thành thạo các ngôn ngữ này có thể chuyển sang học ngôn ngữ Java trong vòng 2 nốt nhạc. Việc học gần như chỉ là so sánh xem có gì giống và khác, như các kiểu dữ liệu, các cấu trúc điều khiển, hỗ trợ OOP… Sẽ không có gì ngạc nhiên nếu một người giỏi C# chỉ sau 1 ngày có thể tham gia vào dự án Java.Tương tự các ngôn ngữ khác, Java cũng có nhiều phiên bản khác nhau, và thể hiện qua các bản đặc tả (https://docs.oracle.com/javase/specs/).

Thành phần thứ hai là Java runtime, tức tất cả những gì để chương trình Java thực thi, đây là phần phức tạp, và mất rất nhiều thời gian để làm chủ. Để hiểu sâu được, bạn cần hiểu những thứ bên dưới giúp chương trình thực thi: quản lý bộ nhớ, class loader, mã bytecode, bộ dọn rác, JIT… Nếu ai học Java chắc hẳn đã từng gặp lỗi Class Not Found khi chạy chương trình, và cũng loay hoay không biết vì sao code mình dịch xong mà khi chạy nó cứ báo không tìm thấy. Muốn xử lý được, bạn sẽ cần biết cách Java runtime tìm các file class: các thư mục, và thứ tự nó sẽ tìm kiếm.Các trình runtime cũng sẽ có các bản đặc tả của nó, trong bản đặc tả đó người ta sẽ mô tả các tính năng nó hỗ trợ, bạn có thể xem trong đường link phía trên.

Thành phần thứ ba là lớn nhất và mất thời gian học nhất: các thư viện Java. Các thư viện được cung cấp sẵn rất lớn, và hầu như chúng ta chỉ bắt đầu với những thứ cơ bản: io, xml, util, swing, awt, net… các phần còn lại sẽ chỉ cần học khi nào cần tới.

Continue reading “GIỚI THIỆU VỀ JAVA”

LAN MAN VỀ VIỆC HỌC

https://vnexpress.net/sa-thai-mua-covid-4127122.html

Những bài viết như thế này luôn gây ra hai luồng ý kiến trái ngược, một bên bênh vực người lao động vì công ty cho nghỉ không đúng luật, một bên lại bên vực công ty khi bắt buộc phải tìm cách cho nghỉ những nhân viên kém hiệu quả nhất.

Kém hiệu quả nhất là gì? Kém hiệu quả nhất không đồng nghĩa với việc bạn là người dở nhất. Nhưng bạn không còn phù hợp với tổ chức đó nữa. Khi đã rơi vào tình thế này thì việc ra đi chỉ là sớm hay muộn, trừ khi bạn quá “mặt dày” để cố đấm ăn xôi 😃.

Tôi sẽ không bàn về việc ta phải làm gì trong hoàn cảnh này, bởi như trên đã nói, chẳng có con đường nào khác ngoài ra đi. Nhưng ta sẽ bàn về cách để không phải rơi vào hoàn cảnh ra đi nhưng không biết đi về đâu.

Trước tiên, ta phải nhìn nhận rằng tự nhiên luôn công bằng, nó có những quy luật của nó và các quy luật này là bất biến. Một cậu trai mới ra trường đã được làm sếp chỉ vì cha cậu ấy là chủ tịch – Điều này có công bằng không? Nếu là không, và cậu ấy cũng phải bắt đầu như mọi người, vậy điều đó có công bằng với cha cậu ấy – người ta phấn đấu cả đời để xây dựng nên công ty hay không? Để đến được đích trước, bạn phải có ít nhất một trong hai lợi thế: hoặc bạn phải chạy nhanh hơn, hoặc phải ở gần đích hơn! Mà việc lựa chọn điểm xuất phát lại không nằm trong tay chúng ta, nên chỉ có một cách duy nhất là phải chạy cho thật nhanh, và chạy cho đúng hướng.

Trong ngành công nghiệp phần mềm, vũ khí cạnh tranh lớn nhất là tri thức, và chỉ có duy nhất một cách để mài dũa vũ khí đó là học. Vậy phải học thế nào?

Continue reading “LAN MAN VỀ VIỆC HỌC”

NÊN SỬ DỤNG MULTI THREADING THẾ NÀO

Sau khi đã biết cách viết chương trình multi-thread, giờ ta sẽ cùng bàn đến vấn đề quan trọng hơn: Khi nào nên dùng MT, và còn có lựa chọn nào khác nữa không?

ℹ️ Multi threading phù hợp với những trường hợp sau đây:

👉 Chương trình cần tính toán nhiều (sử dụng nhiều năng lực tính toán của CPU) và muốn tận dụng nhiều CPU hoặc core khác nhau, mỗi thread sẽ tính toán một bài toán riêng lẻ. Tuy nhiên lưu ý là không phải cứ tạo thread mới thì nó sẽ tận dụng được các nhân khác, nếu bạn có 2 thread nhưng được gán cho cùng một core/cpu thì hiệu năng cũng sẽ không tăng lên. Với các bài toán này, bạn nên tìm hiểu về các thư viện hỗ trợ lập trình song song trên nền tảng của bạn.Ngay cả khi bạn chỉ có một bài toán cần tính, bạn cũng nên đưa vào một thread chạy ngầm bởi 2 lý do:

– Chương trình sẽ không bị khóa cứng lại và trở nên “not responsive”, người dùng có thể theo dõi tiến độ, hoặc hủy nếu quá trình tính toán quá lâu.

Continue reading “NÊN SỬ DỤNG MULTI THREADING THẾ NÀO”

Chuyên mục trả lời câu hỏi

Trả lời:

Ta có thể hiểu thế này, một tiến trình (process) được tạo ra khi bạn tải và chạy một chương trình từ đĩa, nó sẽ có một không gian địa chỉ riêng, độc lập hoàn toàn với các tiến trình khác. Hai tiến trình sẽ nằm ở hai dải địa chỉ khác nhau, nếu muốn nói chuyện thì phải thông qua một cơ chế giao tiếp IPC nào đó (inter-process communication), như TCP/IP, namepipes… Một thread là một luồng xử lý của CPU, là một dãy lệnh mà CPU sẽ thực thi, dãy lệnh đó hiển nhiên sẽ được nạp vào và nằm bên trong một tiến trình.

Có thể hiểu nôm na, mỗi process là một nhà máy, còn các thread là các công nhân. Hai công nhân làm cùng nhà máy thì có thể truy cập vào các tài nguyên chung, còn khác nhà máy thì buộc phải dùng dịch vụ chuyển phát thì mới trao đổi thông tin được. Một nhà máy thì có ít nhất một công nhân – single thread (nhưng cũng có thể có nhiều hơn – multi thread).

Continue reading “Chuyên mục trả lời câu hỏi”

VẤN ĐỀ ĐỒNG BỘ TRUY CẬP DỮ LIỆU

Bài toán đồng bộ

Đối với các chương trình single-thread, ta không cần quan tâm đến việc đồng bộ, bởi chương trình sẽ thực thi theo thứ tự từ trên xuống dưới từng câu lệnh một, trạng thái của chương trình sẽ chỉ bị thay đổi bởi chính nó. Tuy nhiên với các chương trình multi-thread, sẽ xảy ra trường hợp có nhiều hơn một thread cố gắng truy cập vào cùng một biến và gây ra sai sót.

👉 Xét ví dụ sau khi tráo đổi giá trị hai biến x và y (swap):

x = 10;
y = 20;
t = x; 
x = y; (*)
y = t;

Tại vị trí (*), giá trị của x và y bằng nhau, và bằng 20. Đây có thể coi là một trạng thái sai, bởi chỉ có thể x = 10, y = 20 hoặc x = 20, y = 10 sau khi tráo đổi xong. Trước hay sau khi tráo lại thì x * y cũng phải bằng 200, tuy nhiên tại vị trí (*), x * y sẽ là 400.Nếu có một thread thứ hai đọc giá trị của x và y để xử lý công việc, sẽ có một lúc nào đó giá trị nó đọc được sẽ bị sai.Cũng với ví dụ trên, giả sử có 2 thread cùng thực thi, bởi các câu lệnh có thể ngắt quãng và thực thi xen kẽ bởi các thead khác nhau, nên có thể xảy ra trường hợp sau:(thread 1 ký hiệu t1, thread 2 ký hiệu t2)

Continue reading “VẤN ĐỀ ĐỒNG BỘ TRUY CẬP DỮ LIỆU”