Mục lục

Để tiện theo dõi, tôi xin giới thiệu danh mục các chủ đề và bài viết trong blog Đào Hải Nam:
No photo description available.

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é.

Read More
No photo description available.

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.

👉 Trong thiết kế, tính trừu tượng luôn là một ưu tiên hàng đầu, một trong những nguyên tắc thiết kế là áp dụng trừu tượng nhiều nhất có thể, bởi các lợi ích sau:

– Giảm độ phụ thuộc giữa các thành phần, đặc biệt là các thành phần đang được phát triển hoặc thay đổi thường xuyên. Độ phụ thuộc thấp, các lỗi xảy ra sẽ ít ảnh hưởng dây chuyền tới các thành phần khác.

– Dễ dàng thay đổi và mở rộng về sau: khi thiết kế bạn luôn phải tâm niệm là chương trình phải dễ dàng cập nhật, thay đổi, sửa lỗi sau nhiều năm, có thể là 5 năm, 10 năm hoặc thậm chí 20 năm. Bạn phải đảm bảo chi phí để thêm một tính năng mới trong tương lai sẽ tương đương với hiện tại, chứ không phải càng ngày càng tăng lên. Các thành phần mới thêm vào thậm chí không khiến bạn phải biên dịch hoặc triển khai lại các phần đã có.

👉 Trong thời kỳ đầu của OOP, người ta sử dụng thừa kế như một cách để hiện thực tính trừu tượng, lớp cha khai báo các phương thức, lớp con hiện thực hóa các phương thức đó theo cách riêng của chúng. Nhưng nhiều nhà thiết kế tin rằng như vậy vẫn chưa đủ, bởi một lớp thì vẫn là một lớp, nó vẫn mô tả một thực thể nào đó, ngay cả khi nó là lớp abstract. Từ đó interface xuất hiện, interface không được coi là một thực thể, mà chỉ đơn thuần là một bản khai báo, một danh mục các hành vi cần thiết. Hãy thử tìm một cuốn sách về OOP cách đây vài chục năm, các bạn sẽ không tìm thấy chỗ nào nói về interface, thậm chí không có một chương riêng cho abstraction, bởi đơn giản abstraction khi đó vẫn chỉ được nói đến như một phần của polymorphism và inheritance.

👉 Có thể nhìn từ góc độ lập trình bạn không thấy nhiều thay đổi, nhưng từ góc độ thiết kế, interface đại diện cho pattern (hình mẫu) interface/implementation thay vì mô hình thừa kế sử dụng các lớp. Mô hình interface/implementation rộng hơn và khái quát hơn mô hình thừa kế.Tới đây bạn đã thấy sự khác nhau giữa hai cái chưa? Nếu chưa có nghĩa là suy nghĩ của bạn vẫn bị gắn chặt với một ngôn ngữ nào đó cụ thể, hãy thử học thêm một nền tảng/ngôn ngữ mới, hay thử thiết kế một hệ thống nào đó xem sao?Nếu các bạn gửi yêu cầu và thiết kế của các bạn cho tôi, tôi có thể xem và đánh giá giúp các bạn.

No photo description available.

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.

👉 Bởi các thư viện Java rất lớn, và vì Java được hỗ trợ trên rất nhiều loại thiết bị, từ các máy chủ cỡ lớn phục vụ hàng ngàn user, các máy tính để bàn, các thiết bị công nghiệp, đến các thiết bị cầm tay… nên sẽ hợp lý hơn khi chia các tập thư viện theo các lớp thiết bị khác nhau. Từ đó người ta phân các tập thư viện này ra làm 3 loại chính:

– Java Standard Edition (Java SE): Đây là bộ Java cơ bản, chứa các thành phần chính để chương trình Java có thể chạy được, như máy ảo Java, các kiểu dữ liệu, các lớp cơ bản mà hầu như chương trình nào cũng cần đến… Bạn có thể viết tất cả các loại chương trình chỉ với Java SE.

– Java Enterprise Edition (Java EE): Được xây dựng trên nền Java SE, tức các chương trình viết trên Java EE thực chất vẫn là các chương trình Java SE, tuy nhiên Java EE cung cấp thêm các thư viện cũng như môi trường thực thi phục vụ các ứng dụng lớn, các dịch vụ trên máy chủ… Nếu bạn viết một ứng dụng web, bạn sẽ phải dùng một công nghệ Java EE nào đó, biên dịch với các thư viện JavaEE (và tất nhiên cả JavaSE), rồi chạy trên các máy chủ JavaEE (JavaEE server), một số server có thể kể ra như Tomcat, JBoss, Weblogic… Mỗi công nghệ trên JavaEE cũng có một đặc tả và phiên bản, khi tạo ra các JavaEE server, người ta sẽ phải theo hỗ trợ một số công nghệ khác nhau, các công nghệ được hỗ trợ có thể rất khác nhau giữa JavaEE server.

– Java Micro Edition: Được thiết kế cho các thiết bị nhỏ với tài nguyên hạn chế. Khác với Java EE, Java ME không dựa hoàn toàn trên Java SE, tập thư viện trên Java ME chỉ là một tập con của Java SE. Trước thời dại smart phone với Android và iOS, hầu như tất cả các điện thoại đều hỗ trợ Java ME.

👉 Vậy còn Java trên Android?Java trên Android là một platform được thiết kế riêng cho Android, tạm coi nó không phải là Java ME, cũng không phải là Java SE “thuần chủng”, tức không phải thư viện nào trong bộ Java SE cũng được hỗ trợ. Các phiên bản Android trước đây dựa trên Apache Harmony, sau này dựa trên Open JDK. (Thật sự tôi chưa nghiên cứu nhiều về Android source nên chỉ biết dựa trên các tài liệu đọc được).

Hiện tại để viết app trên Android, bạn có rất nhiều lựa chọn khác “hiện đại” hơn: Kotlin, Flutter, RN…

👉 Java hiện tại vẫn đang là một trong những nền tảng phổ biến nhất, ngôn ngữ Java vẫn luôn góp mặt trong các bảng xếp hạng ngôn ngữ phổ biến hàng năm. Đặc biệt trong các ứng dụng lớn, yêu cầu bảo mật cao. Có nhiều lý do cho việc này:

– Thứ nhất là các ứng dụng Java luôn được chạy trên một máy ảo, máy ảo này cách ly ứng dụng khỏi hệ thống và kiểm soát tất cả các thao tác mà ứng dụng thực hiện.

– Thứ hai, Java được thiết kế để “Viết một lần, chạy mọi nơi”, bạn có thể viết, dịch chương trình trên Windows, sau đó triển khai trên một máy chủ Linux hay Unix. Có một điều mà ai cũng biết, đó là các máy chủ Unix được các nhà quản trị tin cậy hơn Windows về mặt bảo mật, và thường xuyên là lựa chọn đầu tiên khi triển khai các ứng dụng tài chính, ngân hàng… các ứng dụng này có vòng đời dài, thời gian phát triển và số tiền đầu tư vào rất lớn. Vì vậy sẽ còn rất lâu chúng mới bị thay thế, đặc biệt trong hoàn cảnh Java vẫn còn làm rất tốt nhiệm vụ của nó.

Nếu đặt ra câu hỏi tại sao JavaScript cũng có khả năng viết một lần chạy mọi nơi, nhưng lại không được ưa chuộng như Java, ta có thể trả lời như sau:

– JS trên server, hay nói cụ thể hơn là NodeJS còn rất non trẻ, cách đây 10 năm, khi Java đang phát triển mạnh mẽ thì NodeJS chỉ mới ra đời.

– Để xây dựng một ứng dụng phức tạp với JS rất khó, có lẽ sẽ dễ dàng hơn với JS khi chia nhỏ ra thành các service, hoặc dùng JS để phát triển các microservice. Nhưng nên nhớ Docker – công nghệ đứng phía sau mô hình này cũng chỉ mới ra đời từ 2013.

– JS không hỗ trợ một mô hình OOP bài bản và hoàn chỉnh như Java. Đúng là JS có OOP, nhưng thật sự rất khó để áp dụng kiến thức OOP designing vào JS. Khi đạt đến một độ phức tạp nhất định, Java cho phép tổ chức, viết code, duy trì đơn giản hơn JS. Docker/NodeJS/microservice giúp giải bài toán phân tán dễ dàng, nhưng JavaEE cũng có EJB và các công nghệ liên quan, vốn được thiết kế để xây dựng các ứng dụng phân tán, đa tầng (multi-tier), về độ mềm dẻo (flexible) có thể không bằng microservice, nhưng đối với các ứng dụng đã triển khai, với mô hình hạ tầng có sẵn thì việc chuyển đổi sang microservice cũng không đem lại lợi ích gì.

👉 Vậy có còn nên học Java không?

Như trên đã nói, Java gần như xuất hiện trong top 3 của tất cả các bảng xếp hạng ngôn ngữ lập trình phổ biến (tìm kiếm với từ khóa “programming languages popularity”), vì vậy hiển nhiên bạn không cần phải lo lắng về độ phổ biến của nó. Tuy nhiên nên nhớ là hiện tại Java thường được dùng phát triển các ứng dụng lớn, hoặc các phần core, vậy nên bạn sẽ phải học nhiều thứ hơn trước khi có thể bắt đầu – bù lại bạn sẽ có thể tham gia sâu hơn, vào nhiều loại dự án khác nhau.

👉 Java và JavaScript, cái nào hơn?

Thật sự trước khi xuất hiện v8/NodeJS, câu hỏi trên là một câu hỏi hài hước ☺️. JS chủ yếu chạy trên trình duyệt, còn Java chạy trên máy chủ hoặc desktop, Java đã từng chạy trên trình duyệt (Java applet) nhưng đó là dĩ vãng xa xưa rồi, vậy nên có thể coi hai thứ này vốn không dẫm lên chân nhau. Nhưng hiện tại, các ứng dụng JS, cũng như các framework dựa trên nền tảng này vô cùng phong phú. Với JS, bạn có thể học và bắt đầu công việc nhanh hơn Java, bạn cũng không cần biết nhiều về OOP, chỉ cần vài tháng bạn đã có thể đi làm được rồi. Đây là một lợi thế rất lớn, nhưng nên nhớ không phải tự nhiên Java lại trở thành một ông lớn trong các nền tảng phát triển ứng dụng như vậy.

Một trong những điều nguy hiểm nhất là bạn tự hài lòng với bản thân: tôi đã rành JavaScript rồi, tôi tự mình làm được một ứng dụng từ A đến Z, tôi thấy JavaScript làm được tất cả những gì .NET, Java làm được. Vậy tại sao tôi phải học thêm một thứ khác? Nó cũng giống như câu hỏi: Tôi biết sửa TV rồi, sao còn phải học sửa điện thoại? (câu trả lời dành cho bạn).

Tôi luôn khuyến khích các bạn học rộng ra, bởi chỉ khi học rộng, bạn mới thấy những hạn chế của nền tảng mà bạn đang theo đuổi, và quan trọng hơn, khi đó bạn mới biết nên học sâu vào cái gì 😏. Phần mềm là thứ thay đổi rất nhanh, cái bạn thành thạo hôm nay có khi sang năm chẳng ai dùng nữa. Bạn luôn phải tìm hiểu xem tương lai sẽ có những gì, đánh giá nó, đặt cược vào nó, học sâu vào TRƯỚC KHI những người khác học.

Có như vậy bạn mới trở thành người dẫn đầu được.

No photo description available.

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?

Trước hết, bạn phải có một mục tiêu. Một trong những lý do các bạn cảm thấy mệt mỏi và mất phương hướng là vì mục tiêu của bạn quá ngắn hạn và bởi vậy – quá thấp. Một bạn sinh viên mới ra trường chỉ có một mục tiêu tìm một công việc trước mắt, thành thạo những công việc rất cơ bản. Khi vào công ty, bạn bị choáng ngợp bởi các anh già hơn đã đi làm 5, 10 năm… Bạn có nghĩ đến việc trở thành một chuyên gia phần mềm, một kỹ sư cao cấp hay một kiến trúc sư phần mềm – những vị trí mà các công ty luôn chào đón không? Bạn đã nghĩ đến việc cần phải làm gì, cần bao nhiêu thời gian để làm điều đó chưa? Nếu chưa, có nghĩa là tầm nhìn của bạn quá ngắn, hay bạn định bụng cứ đi làm bình thường ngày này qua ngày khác, rồi đột nhiên trở thành chuyên gia?

Khi đã có một mục tiêu rồi, bạn sẽ phải tìm hiểu xem mình phải làm gì. Bạn rất muốn trở thành chuyên gia, hay một kiến trúc sư phần mềm. Vậy nhưng thế nào được gọi là chuyên gia, hay công việc của một kiến trúc sư phần mềm là gì bạn đã biết chưa? Nếu ngay cả việc công việc đó là gì bạn cũng không biết thì sao bạn biết được cách để đạt được vị trí đó??? Chỉ khi bạn biết cần làm gì để đạt được mục tiêu thì mới có thể lên kế hoạch được.

Ở đây, tôi xin đưa ra thêm vài gợi ý giúp bạn đi đúng hướng:

👉 Học tiếng Anh thật tốt: mặt bằng lương ở các công ty nước ngoài, nhất là các vị trí làm việc trực tiếp với người nước ngoài cao hơn đáng kể so với phần còn lại. Và thêm nữa, cơ hội của bạn không chỉ gói gọn trong nước, mà sẽ mở rộng ra rất nhiều.

👉 Cố gắng tích lũy kinh nghiệm: Kinh nghiệm có thể có từ công việc, hoặc có thể từ các dự án riêng của bạn. Và theo tôi hầu hết kinh nghiệm tích lũy cho tương lai sẽ đến từ các dự án riêng, các công việc tại công ty hầu hết sẽ chỉ lặp đi lặp lại trong một khuôn khổ nhất định, nếu không có một vị trí mới, hay một dự án mới thì kinh nghiệm sẽ chẳng có thêm gì dù bạn làm bao nhiêu năm đi nữa.Luôn có một dự án cá nhân để làm trong lúc rảnh rỗi sẽ giúp bạn tiến bộ hơn rất nhiều.

👉 Nếu năm kinh nghiệm không phải là thế mạnh của bạn thì việc luyện các chứng chỉ của các hãng lớn như Microsoft, Amazon, Oracle… rất có ích vì kiến thức của chúng rất bài bản, và các chứng chỉ đó được chấp nhận rộng rãi.

👉 Nếu trung bình mỗi ngày bạn không dành ra được 1-2 giờ học thì có nghĩa là bạn đang tụt hậu.Nếu công việc “ổn định” hiện tại của bạn không mang lại ít nhất một trong những thứ sau đây thì nên nghĩ đến việc tìm bến đỗ mới:

👉 Được tiếp cận với các công nghệ/công việc có cơ hội học hỏi cao.

👉 Có cơ hội phát triển lên một vị trí tốt hơn trong vòng 1-2 năm tới.

👉 Mức lương tốt nhưng thời gian vẫn đảm bảo cho bạn làm thêm các dự án cá nhân theo sở thích.Tuy nhiên gợi ý cũng chỉ là gợi ý, chỉ có bạn mới biết cần làm gì. Xác định mục tiêu – lập kế hoạch – thực hiện, chỉ có cách đó mới giúp đạt được những thứ mong muốn.Làm một công việc mà không ai dám đuổi vẫn thích hơn khi có chuyện gì người ta lại cho mình ra đi chứ nhỉ? 😅

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.

Read More
No photo description available.

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).

Read More
No photo description available.

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)

Read More

Cách đây mấy hôm tôi có đưa ra một khảo sát xem mọi người sẽ theo hướng FP hay OOP, vì hay gặp cảnh tranh cãi giữa hai trường phái này. Và thường các cuộc tranh cãi đều không có hồi kết, đơn giản vì ai cũng có lý lẽ của mình, và quan trọng nhất là không có ai có thể đưa ra được những lý do xác đáng để bên kia tin theo.

Trong bài này tôi sẽ mặc nhiên coi các bạn đã hiểu về OOP, và sẽ nói một chút về FP (vì trong blog này chưa có bài nào nói về nó). Nếu như bạn chưa thực sự biết rõ cả OOP lẫn FP thì tất cả những lý lẽ đưa ra sẽ đều là cảm tính, do đó quan điểm đưa ra sẽ dễ trở nên phiến diện và không thuyết phục.

Nhớ tìm đọc lại các bài OOP nếu bạn vẫn chưa nắm rõ nhé ❤️.

ℹ️ Vậy Functional Programming là gì?

Read More