Home Blog Page 112

Hướng dẫn và sử dụng jquery plugin typing để giả hiệu ứng gõ văn bản

Hướng dẫn và sử dụng jquery plugin typing để giả hiệu ứng gõ văn bản

Bài viết được sự cho phép của tác giả Phạm Công Sơn

Đây là plugin giả lập gõ văn bản, rất phù hợp với những web cần hiển thị text dạng ngắn hay slogan hiện ra từ từ bằng hiệu ứng typing. Các bạn có thể tải plugin này tại đây

  15 thư viện slider jquery miễn phí cho dự án website của bạn
  Cách sử dụng các plugins jQuery trong VueJS

1. Dưới đây là demo

2. Hướng dẫn cài đặt

<script type="text/javascript" src="jquery.js"></script> <script type="text/javascript" src="t.min.js"></script>

3. Hướng dẫn sử dụng

Nội dung code Html
<div data-form="typing" class="hide">     <mark><a>Chào mừng các bạn đã đến với blog son20.com của mình</a></mark>     <br/>Hãy chờ mình một chút <del>Khoảng</del> tầm 2 giây thôi rồi thì mình giới thiệu nhé..<ins>2</ins>     <br /><strong>Đây là Plugin giả lập Typing rất thú vị.</strong>     <br /><del></del> để thực hiện giả lập xóa text *<ins>2</ins>     <br /><ints>{numeric}</ints> để thực hiện delay một khoảng thời gian (tính bằng giây)*<ins>2</ins>     <br /><kbd></kbd> để tối ưu việc gõ nhầm *<ins>2</ins>     <br/>Chúc <del style="color:red;border-bottom:1px dashed red;">mọi người</del>các bạn sử dụng plugin này vào những trường hợp hữu ích.     Chờ xíu để chạy lại nhé <ints>2</ints> </div>
Nội dung code javascript
var run = function () {     $("[data-form=typing]").removeClass("hide").t({         speed: 50,                             pause_on_tab_switch: true,         pause_on_click: true,         beep: true,         fin: function () { run(); }     }); } run();
Tham số Giá trị Ghi chú
speed numeric Tốc độ giả lập gõ văn bản, càng lớn thì giả lập tốc độ gõ càng chậm
pause_on_tab_switch boolean Nếu là true thì sẽ dừng giả lập gõ khi trình duyệt mất focus
pause_on_click boolean Nếu là true thì sẽ dừng giả lập gõ khi click vào hiển thị
beep boolean Nếu là true thì sẽ có âm thanh gõ khi giả lập typing
fin function sự kiện khi kết thúc giả lập

Chúc các bạn sử dụng plugin vào những lúc thích hợp

Sơn 20

Bài viết gốc được đăng tải tại sonpc20.com

Có thể bạn quan tâm:

Xem thêm Tuyển dụng JQuery hấp dẫn trên TopDev

PHP: Nhà tuyển dụng cần những gì?

Tuyển dụng PHP: Nhà tuyển dụng cần những gì?

Bài viết được sự cho phép của tác giả Trần Thị Thu Hà

Để tuyển dụng được một lập trình viên tốt, thì các nhà tuyển dụng thường đặt khá nhiều kỳ vọng vào các kỹ năng mà lập trình viên đã tự trang bị được cho mình.

Trong bài này, trong lĩnh vực PHP, các nhà tuyển dụng cần gì ở một lập trình viên? Bạn đã chuẩn bị được những kỹ năng gì để đi xin việc tuyển dụng PHP?

1. Những kỹ năng bắt buộc

  • Nắm chắc kiến thức cơ bản về lập trình web với HTML, CSS (và cả JS thì là tốt nhất)

PHP là để lập trình web, mà HTML+CSS(+JS) là bộ cơ sở đi với nhau, và do đó, bạn muốn làm web mà không biết HTML+CSS thì chắc chắn là không thể được. Thực tế, với HTML+CSS bạn không cần phải biết tường tận mọi ngõ ngách, không cần phải siêu đẳng, thế nhưng những thứ thường gặp bạn cần phải nắm rõ.

  •  Về ngôn ngữ PHP

Bạn làm về PHP, rõ ràng bạn phải hiểu được cơ bản về nó. Cách bạn đặt biến như nào, đặt hàm như nào,… rồi những vấn đề cơ bản như: hiển thị một chuỗi lên HTML bằng PHP như thế nào, PHP kết nối đến DB như là MySQL ra sao,… Bạn có thể lúc nhớ lúc quên, nhưng khi đưa code có sẵn ra bạn phải đọc được và hiểu được, rồi mới tính đến chuyện tự tay code được.

  10 PHP Instagram Scripts & Widgets tốt nhất
  10 điều bạn cần biết về PHP7

2. Những kỹ năng cạnh tranh để làm lợi thế

Nếu bạn đã thành thạo một số kỹ năng dưới đây, ngoài việc tăng khả năng kiếm được một công việc như ý về tuyển dụng PHP, bạn còn có lợi thế nhất định khi đàm phán lương bổng.

  • Thành thạo nhiều các PHP framework

Với cộng đồng PHP lớn mạnh, cũng như vị trí quan trọng của bộ sậu PHP-MySQL trong thế giới web cộng với nhu cầu tuyển dụng PHP ngày càng lớn thì việc mà có vô số các sản phẩm opensource, hoặc có phí là điều dễ hiểu. Tương tự đó, rất ít các công ty phát triển web làm từ đầu sản phẩm của mình, mà thường dựa vào một nền tảng framework nào đó để tuỳ biến. Nhất là các công ty ở Việt Nam, có rất ít công ty bỏ tiền ra đầu tư làm từ đầu sản phẩm của mình. Do đó, bạn nắm được nhiều framework thì bạn lại càng có nhiều lợi thế hơn khi xin việc cũng như khi đàm phán lương bổng.

Nhu cầu tuyển dụng PHP ngày càng lớn.

Các framework đáng chú mà các bạn cần bỏ thời gian nghiên cứu, làm thử gồm:
– Về CMS: WordPress, Joomla, CakePHP, Yii, Laravel, …
– Về eCommercer: Magento, OpenCart, Shopify,…
– Ngoài ra, còn có một số khác, mặc dù ít gặp ở Việt Nam nhưng không phải là không cần: CRM như Sugar hoặc Tiger,..

  • Thành thạo làm Responsive

Với thời điểm bùng nổ smartphone, tablet iOS, Android như hiện tại, việc có thêm kỹ năng làm web Responsive là cực kỳ quan trọng. Các website lớn, hoặc chuyên nghiệp sẽ yêu cầu điều này. Việc học cách để làm responsive này cũng không tốn nhiều thời gian, cũng như PHP, hiện nay có rất nhiều framework giúp cho các bạn về việc này.

  • Thành thạo các Javascript framework, tối đặc biệt JQuery

Tương tự với các quan điểm trên, bạn cũng nên nắm được vững cách sử dụng JQuery. Tài liệu hướng dẫn rõ ràng dễ hiểu, các biện pháp giải quyết khó khăn bằng JQuery nhiều vô kể. Và cũng có vô số người sẵn sàng giúp bạn trên StackOverflow.

Tìm việc làm PHP đãi ngộ tốt trên TopDev

3. Một số kỹ năng hoặc hiểu biết khác

Ngoài những điểm đề cập trên, thật tuyệt vời nếu nhà tuyển dụng cũng biết được bạn thành thạo, hoặc đã từng làm, hoặc có hiểu biết, hoặc thậm chí là có nghe nói đến một số các thứ sau đây:
– Kỹ thuật về AJAX với JQuery.
– JSON
– Restful Webservices
– Tương tác với web API, request header, response header
– AngularJS
– Thành thạo các tool như Sublime Text, Notepad++, IntelliJ IDEA,…
– Cách deploy một web PHP lên hosting bằng FTP, CPanel,…
Với những chia sẻ trên hy vọng sẽ giúp ích cho các bạn trong quá trình đi xin việc. Chúc các bạn thành công!

Bài viết gốc được đăng tải tại smartjob.vn

Có thể bạn quan tâm:

Xem thêm việc làm php hcm hấp dẫn trên TopDev

Nguyên tắc “Hãy làm gì đó đi” – Làm thế nào để có động lực thực hiện bất cứ điều gì

Nguyên tắc “Hãy làm gì đó đi” – Làm thế nào để có động lực thực hiện bất cứ điều gì

Bài viết được sự cho phép của tác giả Tino Phạm

Tôi đã làm việc như một nhà tư vấn về phát triển bản thân trong phần lớn cuộc đời. Tôi đã đi qua rất nhiều khái niệm và ý tưởng cũng như phát minh ra một số khái niệm cho riêng mình. Nhưng sau đây là một trong những ý tưởng quan trọng nhất mà tôi đã có:

Hành động không chỉ chịu ảnh hưởng của động lực mà nó còn là nguyên nhân gây ra động lực.

  "Bắt đầu từ vị trí dev, làm tốt sẽ được trao cơ hội trở thành leader"
  10 ngôn ngữ phát triển nhanh nhất theo GitHub thống kê năm 2024

Vì sao chúng ta hành động?

Hầu hết mọi người chỉ cam kết hành động nếu họ được thúc đẩy ở một mức độ nhất định. Và họ chỉ có động lực khi họ cảm thấy một nguồn cảm hứng cảm xúc. Một người chỉ bắt đầu có động lực để học tập cho kỳ thi khi người đó hình dung ra những hậu quả nếu họ thi rớt. Một người quyết định học một loại nhạc cụ nào đó khi họ cảm thấy được truyền cảm hứng vì có thể chơi nhạc cho bạn bè và người thân của họ nghe.

Và tất cả chúng ta đã từng buông lơi mọi thứ vì thiếu động lực ít nhất một lần trong đời. Đặc biệt là trong thời điểm mà chúng ta không nên. Chúng ta cảm thấy thờ ơ và lãnh đạm khi hướng tới một mục tiêu nhất định đã đặt ra cho chính mình bởi vì chúng ta thiếu động lực và chúng ta thiếu động lực bởi vì chúng ta không cảm thấy bất kỳ khao khát về cảm xúc nào để thực hiện điều đó.

Cảm hứng → Động lực → Hành động mong muốn

Nhưng có một vấn đề với khuôn mẫu này: Phần lớn những thay đổi và hành động mà chúng ta cần trong cuộc sống đều được truyền cảm hứng bởi những cảm xúc tiêu cực và chính những cảm xúc đó lại cản trở chúng ta thực hiện những hành động đó.

Nếu một người đang cố hàn gắn mối quan hệ của họ với người khác, những cảm xúc nội tại (những tổn thương, oán giận, sự trốn tránh) hoàn toàn đi ngược lại những hành động cần thiết để hàn gắn (đối mặt, trung thực và giao tiếp).

Cảm giác xấu hổ về cơ thể tạo nên động lực mong muốn giảm cân của một người, nhưng cũng chính cảm xúc xấu hổ đó lại cản trở họ đi đến phòng tập gym vì lo sợ bị người khác chê cười.

Những tổn thương trong quá khứ, kỳ vọng tiêu cực và cảm giác tội lỗi, xấu hổ và sợ hãi thường khiến chúng ta trốn tránh những hành động cần thiết để vượt qua những tổn thương, kỳ vọng và cảm xúc tiêu cực đó.

Động lực thực sự hoạt động như thế nào?

Chuỗi động lực không chỉ gồm 3 phần, mà nó là một vòng lặp vô hạn:

Cảm hứng → Động lực → Hành động → Cảm hứng → Động lực → Hành động → …

Hành động của bạn sẽ tạo ra các phản ứng về cảm xúc và cảm hứng tiếp theo và lặp đi lặp lại thúc đẩy những hành động trong tương lai. Lợi dụng kiến thức này, chúng ta có thể định hướng lại tư duy của chúng ta theo cách sau:

Hành động → Cảm hứng → Động lực

Kết luận là nếu bạn không có động lực để thực hiện một sự thay đổi quan trọng trong cuộc sống của bạn, thì hãy làm một cái gì đó, bất cứ điều gì, và sau đó khai thác các phản ứng với hành động đó như một cách để bắt đầu thúc đẩy bản thân.

Tôi gọi điều này là Nguyên tắc “Hãy làm gì đó đi”. Và tôi đã phát triển nó trong những năm làm việc như một nhà tư vấn giúp đỡ mọi người thoát ra khỏi nỗi sợ hãi và sự thờ ơ để hành động.

Nó bắt nguồn từ chủ nghĩa thực dụng đơn giản: Bạn trả tiền cho tôi để bạn được ở đây và làm điều gì đó. Tôi không quan tâm, hãy làm điều gì đó đi!

Những gì tôi tìm thấy là thường khi họ làm một cái gì đó, thậm chí là những hành động nhỏ nhặt nhất, nó sẽ sớm cung cấp cho họ nguồn cảm hứng và động lực để làm một điều gì đó khác. Họ đã gửi một tín hiệu cho chính mình, “OK, tôi đã làm điều đó, tôi đoán tôi có thể làm nhiều hơn.” Và cứ chậm rãi như vậy, chúng tôi bắt đầu làm cho mọi thứ tiến triển tốt hơn.

Làm thế nào để có động lực làm bất cứ điều gì?

Qua nhiều năm, tôi đã áp dụng Nguyên tắc “Làm Cái Gì Đó” trong cuộc sống của chính mình.

Ví dụ rõ nhất chính là trang web cá nhân và các hoạt động kinh doanh trực tuyến của tôi. Tôi làm việc cho bản thân mình. Tôi không có một ông chủ nói với tôi phải làm gì và không được làm gì. Tôi cũng thường gặp rủi ro về đầu tư cá nhân, cả về tài chính lẫn tình cảm. Đôi khi có những lúc căng thẳng thần kinh, và những cảm giác về sự nghi ngờ cũng như sự không chắc chắn nảy sinh. Và khi không có ai xung quanh thúc đẩy bạn, ngồi một chỗ và xem lại chương trình truyền hình mỗi ngày có thể nhanh chóng trở thành một lựa chọn hấp dẫn hơn.

Hai năm đầu tiên tôi làm việc cho bản thân mình, cả tuần trôi đi mà tôi không làm được gì nhiều bởi vì tôi cứ luôn lo lắng và căng thẳng về những gì tôi phải làm. Và quá dễ để bỏ cuộc. Tôi đã nhanh chóng học được rằng mình phải ép buộc bản thân làm một việc gì đó. Nếu tôi cần phải thiết kế trang web, tôi sẽ buộc mình ngồi xuống và nói “Được rồi, tôi sẽ thiết kế phần tiêu đề ngay bây giờ!” Nhưng ngay sau khi phần tiêu đề đã được hoàn tất, tôi thấy mình đang tiếp tục thực hiện những phần tiếp theo của trang web. Và trước khi tôi nhận ra được điều đó, tôi đã tràn đầy năng lượng và chú tâm vào dự án.

Tôi cũng thường xuyên áp dụng nó trong cuộc sống của mình. Nếu tôi sắp sửa giải quyết một dự án lớn mà tôi đang lo lắng, hoặc nếu tôi cảm thấy bản thân mình nên đi ra ngoài để gặp gỡ nhiều người hơn, tôi sẽ áp dụng nguyên tắc “Hãy làm gì đó đi”. Thay vì mong đợi một kết quả lớn, tôi sẽ chỉ quyết định “OK, bắt đầu một bản phác thảo thôi!” hoặc “OK, tôi sẽ đi ra ngoài làm một chai bia và xem những gì đang diễn ra!”

Giáo viên dạy Toán thời trung học của tôi đã từng nói: “Nếu các em không biết làm cách nào để giải một bài toán, cứ viết một cái gì đó, bộ não sẽ tự động tìm ra cách để thực hiện những bước tiếp theo”. Và cho đến ngày nay, lời khuyên đó vẫn đúng. Bản thân hành động tự nó sẽ truyền cảm hứng cho những suy nghĩ và ý tưởng mới dẫn dắt chúng ta đến những phương pháp giải quyết các vấn đề trong cuộc sống. Những cái nhìn sâu sắc sẽ không đến nếu chúng ta chỉ đơn giản ngồi im và suy nghĩ về nó.

Gần đây tôi đã nghe một câu chuyện về một tiểu thuyết gia đã viết được hơn 70 cuốn tiểu thuyết. Có người hỏi ông ấy làm cách nào mà ngài có thể viết nhất quán và duy trì được cảm hứng mỗi ngày như vậy. Ông ấy đã trả lời: “Mỗi ngày cố gắng viết 200 từ, chỉ có vậy!”. Ý tưởng ở đây là nếu chúng ta buộc mình phải viết 200 từ mỗi ngày, chính 200 từ đó sẽ truyền cảm hứng cho chúng ta tiếp tục viết, và đến khi nhận ra thì ta đã có hàng ngàn từ trên bản thảo.

Bạn có thể đã nhận ra khái niệm này ở đâu đó. Nhưng không quan trọng nó đến với bạn bằng hình thức nào, đó là một lối suy nghĩ vô cùng hữu ích và là một thói quen tốt cần được áp dụng.

Càng trải nghiệm nhiều tôi càng thấm thía rằng thành công trong bất cứ lĩnh vực nào chỉ phụ thuộc ít đến hiểu biết hay tài năng mà gắn kết chặt chẽ với hành động được bổ trợ bởi kiến thức và tài năng.

Bạn có thể thành công trong một lĩnh vực nào đó dù có thể hiện tại bạn không biết bạn đang làm gì. Bạn cũng có thể thành công dù không có tài năng đặc biệt nào trong lĩnh vực đó. Nhưng bạn sẽ không bao giờ thành công ở bất cứ lĩnh vực nào nếu không hành động. Không bao giờ.

Nguyên tác: How to Get Motivated and Take Action: The “Do Something” Principle

Tác giả: Mark Manson

Biên dịch: 1tach.com

Bài viết gốc được đăng tải tại thangphampt.wordpress.com

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Lập trình IOS: Làm sao để viết code swift đúng chuẩn thế giới?

Lập trình IOS: Làm sao để viết code swift đúng chuẩn thế giới?

Bài viết được sự cho phép của tác giả Lê Xuân Quỳnh

Nhiều bạn newbie sẽ rất khó trả lời câu hỏi: Làm sao để viết code swift đúng chuẩn thế giới? Bạn viết code và người khác đọc được một cách dễ dàng, tuân theo tiêu chuẩn của cộng đồng Swift.

Tuyển ios lương cao tại Việt Nam nhiều ngành nghề

  3 sai lầm các iOS Developers thường mắc phải
  iOS - Tạo chứng chỉ phân phối và tệp .p12 trên MacOS

Khi viết ngôn ngữ lập trình nói chung, Swift nói riêng không ai có thể nói bạn viết sai hay đúng như nào. Ví dụ đoạn code sau:

class classSample {
    var BienGido = ""

    func TenHam() {
        print(BienGido)
    }
}

Khi biên dịch chương trình, nó không báo lỗi. Nhưng đoạn code trên mắc 3 lỗi code style nghiêm trọng:

  1. Tên lớp bắt đầu bằng chữ thường. Luật bất thành văn, khi đặt tên class ở đa số tất cả các ngôn ngữ lập trình, người ta đều phải bắt đầu bằng chữ in hoa. Lý do là: tên lớp là 1 class – nó là 1 danh từ. Ở bộ môn tiếng Việt lớp 3, có quy định: danh từ chỉ tên riêng đều phải viết hoa, ví dụ: Hà Nội, Hồ Chí Minh, Lào Cai.. Cũng tương tự, ở programing language cũng có quy luật tương tự.
  2. Đặt tên biến bắt đầu bằng chữ hoa. Tên biến ở đây là thuộc tính để lưu trữ giá trị của class. Do vậy bạn không thể đặt tên viết hoa được, vì nó đại diện cho nhiều đối tượng kế thừa từ lớp. Bạn không thể nói là tim là 1 danh từ riêng được. Vì con người nào cũng có tim cả.
  3. Tên hàm bắt đầu bằng chữ hoa. Tương tự, tên hàm là phương thức cho class, cho nên nó cũng là chung cho các đối tượng kế thừa từ lớp. Nó bắt buộc phải viết thường.

Sau khi sửa lại, đoạn code sẽ như sau:

class ClassSample {
    var bienGido = ""

    func tenHam() {
        print(bienGido)
    }
}

Tuy nhiên, với 1 bạn mới dấn thân vào con đường lập trình, thì ai sẽ là người nhắc nhở bạn những rule này? Thật may mắn, Swift đã có 1 thư viện hỗ trợ cho bạn viết code 1 cách clean nhất, lỡ bạn có đặt tên biến viết hoa hay tên class viết thường như trên, thì nó tự động báo cho bạn biết để sửa, nhằm đảm bảo code là đẹp nhất.

Tin tôi đi, khi bạn dùng library này, bạn sẽ ngày càng chuẩn chu hơn trong việc viết code và tự tin phang vào đứa nào dám bảo bạn viết sai quy tắc của IOS programing.

Tên của em nó là SwiftLint

Đầu tiên bạn cần phải cài đặt em nó vào project mới của bạn. Project của bạn có thể là đã có sẵn hoặc tạo mới từ đầu, bạn thoải mái chọn lựa.

Cách cài đặt có thể xem readme của nó, hoặc không thì tôi làm đơn giản như sau:

Nếu bạn thích Homebrew, thì bạn gõ dòng lệnh:

brew install swiftlint

Còn nếu đam mê CocoaPods thì gõ:

pod init
pod 'SwiftLint'

Đọc đến đây có nhiều bạn hỏi tôi là “Ơ thế Homebrew là gì mà CocoaPods là gì?” Bạn ơi, ngồi xuống đây làm điếu thuốc, uống chén nước để tôi nói bạn nghe này:

  • Homebrew và CocoaPods là 2 thư viện hỗ trợ bạn cài thư viện ngoài 1 cách nhanh chóng và đơn giản bằng dòng lệnh.

Mặc định máy Macbook của bạn sẽ không có cài đặt nó đâu, và nếu bạn muốn chơi với 2 em nó thì có 2 cách: 1 là bạn google từ khóa “cách cài đặt Homebrew” hay là CocoaPods, sau đó bạn tìm 1 video nào đó trên youtube chẳng hạn, xem rồi thẩm thôi. Cách 2 là đợi tôi có thời gian tôi giải thích bọn nó làm gì. Bật mí là để hiểu bản chất hơn về việc xây dựng thư viện thì bạn dùng Homebrew hay hơn CocoaPods, sau này có thời gian chúng ta sẽ xây dựng các library của các bạn và đẩy lên cho cộng đồng nhé. Bạn sẽ hiểu hơn các khái niệm static hay dynamic library. Còn bây giờ chưa phải lúc làm chuyện đó 😀 chúng ta vẫn còn non.

Quay lại với swiftLint, hiện tại khi cài đặt thư viện xong, bạn mở lên thì nó vẫn chưa hoạt động với project của bạn. Chúng ta cần giao thông với em ấy và thực hiện 1 vài bước setting nhỏ như sau:

  1. Bạn vào setting -> Chọn vào tab Build Phases và nhấn vào nút + -> “New Run Script Phase”. Thêm đoạn script sau:
"${PODS_ROOT}/SwiftLint/swiftlint"

Đoạn code trên nhằm báo cho Xcode dùng Swiftlint để check code convention.

Bạn sửa tên Run scipt thành swiftlink. Sau đó kéo cái script này lên gần trên cùng, sau cái [CP] Check Pods Manifest.lock như hình:

Lập trình IOS: Làm sao để viết code swift đúng chuẩn thế giới?

Để kiểm tra lại, bạn thử sửa đoạn code tên class viết thường xem nó báo lỗi không nha!

Lập trình IOS: Làm sao để viết code swift đúng chuẩn thế giới?
Lỗi vì tên class viết thường

Thử với nhiều code lỗi như sau:

import Foundation

class classSample {
    enum enumLoi {
        case case1
        case Case2
    }
    var BienGido = ""

    func TenHam() {
        var EnumLoi: enumLoi = .case1
        switch EnumLoi {
        case .case1:
            print("case1")
        case .Case2:
            print("case2")
            break
        }
        print(BienGido)
    }
}

Thông báo lỗi bạn thu được:

Lập trình IOS: Làm sao để viết code swift đúng chuẩn thế giới?
Các lỗi code sinh ra

Các dòng đỏ báo lỗi bạn có thể dịch như sau:

  1. Tên phải uppercase, viết hoa chữ đầu
  2. enumLoi cũng phải viết hoa chữ đầu
  3. Case2 phải viết chữ thường
  4. Tên biến không được viết hoa chữ đầu
  5. Tên hàm phải bắt đầu bằng chữ thường
  6. Tương tự 5
  7. Trong case đã có lệnh print nên không cần thiết phải có break

Sau khi chuẩn hóa ta có đoạn code sau:

class ClassSample {
    enum EnumDung {
        case case1
        case case2
    }
    var bienGido = ""

    func tenHam() {
        var enumDung: EnumDung
        enumDung = .case1

        switch enumDung {
        case .case1:
            print("case1")
        case .case2:
            print("case2")
        }
        print(bienGido)
    }
}

Ồ vậy là bây giờ bạn đã yên tâm mỗi khi viết code, có quên có sai ở đâu đo thì yên tâm đã có thằng check cho bạn rồi. Và đảm bảo sau 1 thời gian sử dụng swiftlint thì bạn viết code sẽ chuẩn mực hơn, sexy hơn.

Hi vọng bài viết này sẽ giúp được cho các bạn ngày càng phát triển kỹ năng coding của mình.

Source tham khảo:

https://github.com/codetoanbug/CodestyleSample

Bài viết gốc được đăng tải tại codetoanbug.com

Có thể bạn quan tâm:

Xem thêm Việc làm it swift, ios hấp dẫn trên TopDev

Dependency Injection – Web API ( C# )

Dependency Injection – Web API ( C# )

Bài viết được sự cho phép của tác giả Tino Phạm

1. Dependency Injection là gì?

Hiện nay, các lập trình viên hay lẫn lộn giữa các khái niệm Dependency Inversion, Inversion of Control (IoC), Dependency Injection (DI). Ba khái niệm này tương tự nhau nhưng không hoàn toàn giống nhau.

Sự khác biệt giữa 3 khái niệm trên:

  • Dependency Inversion: Đây là một nguyên lý để thiết kế và viết code.
  • Inversion of Control: Đây là một design pattern được tạo ra để code có thể tuân thủ nguyên lý Dependency Inversion. Có nhiều cách hiện thực pattern này: ServiceLocator, Event, Delegate, … Dependency Injection là một trong các cách đó.
  • Dependency Injection: Đây là một cách để hiện thực Inversion of Control Pattern (Có thể coi nó là một design pattern riêng cũng được). Các module phụ thuộc (dependency) sẽ được inject vào module cấp cao.

Ghi chú: Đôi khi chúng ta so sánh giữa Dependency Injection với Abstraction Factory Design Pattern. Thế những có 1 chút khác biệt giữa hai phương pháp này, đó là DI có một Framework làm việc phía sau nó để gọi các factory và các service đã đăng ký.

18 Web Developer Jobs

Tóm lại, Dependency Injection (DI) là một mẫu thiết kế phần mềm (software design parttern). Đây là cách tuyệt vời để giảm các kết nối chặc chẽ giữa các thành phần của phần mềm (software components). Nó cho phép chúng dễ dàng quản lý các thay đổi trong tương lai cũng như quản lý những hệ thống phần mềm phức tạp dễ hơn.

Ưu điểm

  • Giảm sự kết dính giữa cách thành phần của phần mềm. Hay gọi là giảm sự phụ thuộc của các thành phần với nhau.
  • Dễ bảo trì và dễ thay đổi khi có nhu cầu. (không làm ảnh hưởng đến các thành phần khác trong cùng 1 hệ thống)
  • Tăng khả năng tái sử dụng.
  • Dễ viết Unit Test và kiểm thử.

Nhược điểm: 

  • Sử dụng interface nên đôi khi sẽ khó debug, do không biết chính xác module nào được gọi.
  • Làm tăng độ phức tạp của code.

2. Các dạng Dependency Injection

  • Constructor Injection: Các dependency sẽ được container truyền vào (inject vào) 1 class thông qua constructor của class đó. Đây là cách thông dụng nhất.
  • Setter Injection: Các dependency sẽ được truyền vào 1 class thông qua các hàm Setter.
  • Interface Injection: Class cần inject sẽ implement 1 interface. Interface này chứa 1 hàm tên Inject. Container sẽ injection dependency vào 1 class thông qua việc gọi hàm Inject của interface đó. Đây là cách rườm rà và ít được sử dụng nhất.

3. Mục đích của Dependency Injection là gì?

Chúng ta cần biết mục đích của DI dùng làm gì thì mới có thể áp dụng vào dự án của mình được và sử dụng loại DI nào cho phù hợp.

Với cách code thông thường, các module/class cấp cao sẽ gọi các module cấp thấp. Module/class cấp cao sẽ phụ thuộc và module/class cấp thấp, điều đó tạo ra những phụ thuộc giữa chúng (gọi là dependency). Khi module/class cấp thấp thay đổi, module/class cấp cao phải thay đổi theo. Một thay đổi sẽ kéo theo hàng loạt thay đổi, giảm khả năng bảo trì của code. Nếu bạn đang làm trên một dự án lơn thì việc thay đổi sẽ là điều kinh khủng đối với bạn (bạn sẽ sợ sửa cái này ảnh hưởng đến cái khác vì chúng đang có 1 sự phụ thuộc lẫn nhau mà).

Vậy nếu tuân theo Dependendy Inversion principle, các module cùng phụ thuộc vào 1 interface không đổi. Ta có thể dễ dàng thay thế, sửa đổi module cấp thấp mà không ảnh hưởng gì tới module cấp cao.

  10+ tools và extensions tuyệt vời cho GraphQL APIs
  3 bước tối ưu hiệu năng React App bằng các API mới của React

4. Viết code để hiểu về Dependency Injection

Mình phải công nhận là lý thuyết về thằng DI hơi khó tiêu, bạn cần phải đọc nhiều nguồn khác nhau bao gồm tiếng anh và tiếng việt để không bị bỏ xót và nhầm lẫn thông tin.

Bây giờ, mình có project đơn giản là đọc và hiển thị thông tin từ Database. Chúng ta sẽ cùng xem và so sánh giữa cách viết thông thường và cách viết sử dụng Dependency Injection để hiểu rõ hơn nhé.

Dependency Injection – Web API ( C# )

Nhìn hình trên, Tôi giả sử rằng lúc ban đầu ứng dụng của chúng ta chỉ cần lấy thông tin từ SQL database và hiện thị. vơi làm thông thường, chúng ta sẽ bắt đầu viết class GetMessageFromDatabase. hàm Main sẽ gọi class DisplayMessage và class DisplayMessage cần khởi tạo class GetMessageFromDatabase để lấy thông tin từ Database. Vài tháng sau, chúng ta nhận được yêu cầu từ khách hàng là họ muốn lấy thông tin từ Database và XML file. Vậy là chúng ta lại viết thêm class GetMessageFromXML để lấy thông tin từ XML file. Sau đó vài tháng, khách hàng lại muốn lấy thêm thông tin từ Text file và chúng ta lại ngồi viết thêm class GetMessageFromText tương ứng.

Vấn đề phát sinh là mỗi lần thêm một datasource mới (database, xml, text file) chúng ta cần phải viết một class để lấy dữ liệu tương ứng, sau đó lại phải sửa class DisplayMessage để nó khởi tạo và lấy đúng datasource mình cần. Nếu là một hệ thống lơn thì việc thay đổi này sẽ là một vấn đề lớn và mang lại nhiều phiền toái.

Mục đích của chúng ta cần là viết code theo một cách mà khi cần thêm vào một nguồn dữ liệu mới, thì chỉ cần update lại lời gọi datasource ở hàm Main thôi. Chúng ta không cần thay đổi code ở class DisplayMessage để thích ứng với các loại datasource mới được thêm vào.

Code không dùng Dependency Injection:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            DisplayMessage dm = new DisplayMessage();
            dm.ShowMessage();
        }
    }

    public class DisplayMessage
    {
        GetMessageFromDatabase Gmd;
		
        public DisplayMessage()
        {
            Gmd = new GetMessageFromDatabase();
        }

        public void ShowMessage()
        {
            Console.WriteLine(Gmd.GetMessage());
            Console.ReadLine();
        }
    }

    public class GetMessageFromDatabase
    {
        public string GetMessage()
        {
            //Pretend this comes from the database
            return "Hi from database";
        }
    }
}

Mọi thứ OK, giả sử vài tháng sau chúng ta cần lấy nguồn dữ liệu từ XML dựa vào tham số ở hàm Main. Vậy chúng ta cần phải thêm class GetMessageFromXML vào code của mình. Đồng thời chúng ta cần phải sửa lại một chút code ở  hàm Main và class DisplayMessage. Bây giờ code của chúng ta sẽ như sau:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
	class Program
	{
		static void Main(string[] args)
		{
			DisplayMessage dm = new DisplayMessage(args[0].ToString());	
			dm.ShowMessage();
		}
	}
	
	public class DisplayMessage
	{
		string source;
		
		public DisplayMessage(string s)
		{
			source = s;
		}
		
		public void ShowMessage()
		{
			if (source.ToUpper() == "DATABASE")
			{
				GetMessageFromDatabase Gmd = new GetMessageFromDatabase();
				Console.WriteLine(Gmd.GetMessage());
				Console.ReadLine();
			}
			else if (source.ToUpper() == "XML")
			{
				GetMessageFromXML Gmx = new GetMessageFromXML();
				Console.WriteLine(Gmx.GetMessage());
				Console.ReadLine();
			}
		}
	}

	public class GetMessageFromDatabase
	{
		public string GetMessage()
		{
			//Pretend this comes from the database
			return "Hi from database";
		}
	}
	
	public class GetMessageFromXML
	{
		public string GetMessage()
		{
			//Pretend this comes from an XML file
			return "Hi from XML";
		}
	}
}

Bây giờ giả sử vài tháng sau nữa chúng ta lại cần lấy dữ liệu từ file Text dựa vào tham số truyền vào ở hàm Main. Giờ mình làm gì đây?  viết thêm class GetMessageFromTextFile, rồi sửa lại code của class DisplayMessage nửa hả?

Bạn có thấy sự phụ thuộc của class DisplayMessage khi thực thi thế nào chưa? Đó là nó phải thay đổi dựa vào nguồn dữ liệu được lấy.

Inversion of Control  cố gắng làm cho class DisplayMessage và các class dữ liệu lấy ra hoàn toàn độc lập với nhau. Inversion of Control (IoC) thường được thực thi bằng việc áp dụng Dependency Injection (DI) như mình đã có nhắc ở phần định nghĩa.

Bây giờ chúng ta sẽ xem đoạn code trên dược áp dụng DI vào thì nó sẽ như thế nào nhé.

Code dùng Dependency Injection:

Trong đoạn code bên dưới tôi sẽ dùng 1 trong 3 loại Dependency Injection đó là Constructor Injection.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
	public interface IGetData
	{
		string GetMessage();
	}
	
	class Program
	{
		static void Main(string[] args)
		{
			IGetData IG;
			string source = args[0].ToString();
			if (source.ToUpper() == "DATABASE")
			{
				IG = new GetMessageFromDatabase();
			}
			else if (source.ToUpper() == "XML")
			{
				IG = new GetMessageFromXML();
			}
			else if (source.ToUpper() == "TEXT")
			{
				IG = new GetMessageFromTextFile();
			}
			else
			{
				IG = new GetMessageFromDatabase();//default set to database
			}
			
			DisplayMessage dm = new DisplayMessage(IG);
			dm.ShowMessage();
		}
	}
	
	public class DisplayMessage
	{
		IGetData IGLocal;
		
		public DisplayMessage(IGetData IG)
		{
			IGLocal = IG;
		}
		
		public void ShowMessage()
		{
			Console.WriteLine(IGLocal.GetMessage());
		}
	}

	public class GetMessageFromDatabase : IGetData
	{
		public string GetMessage()
		{
			//Pretend this comes from the database
			return "Hi from database";
		}
	}

	public class GetMessageFromXML : IGetData
	{
		public string GetMessage()
		{
			//Pretend this comes from an XML file
			return "Hi from XML";
		}
	}

	public class GetMessageFromTextFile : IGetData
	{
		public string GetMessage()
		{
			//Pretend this comes from an Text file
			return "Hi from Text file";
		}
	}
}

Như bạn thấy ở ví dụ trên, việc tiêm (injecting) vào các phụ thuộc (dependencies) thông qua constructor (), Tôi đã tách class DisplayMessage và các class lấy dữ liệu (ex: class GetMessageFromDatabase ,…. ). Tôi có thể thêm nhiều class mới  để lấy data nêu tôi muốn mà không cần phải sửa lại class DisplayMessage, miễn sao những class đó phải được kế thừa (inherit) từ interface IGetData. Nghĩa là, mọi thứ ở đây sẽ phụ thuộc vào chỉ 1 Interface. Đây đều chúng ta mong muốn (giảm được sự phụ thuộc – reduce dependencies ).

Hy vọng sẽ giúp bạn nắm được cơ bản về khái niệm và cách sử dụng Dependency Injection.

Bài viết gốc được đăng tải tại thangphampt.wordpress.com

Có thể bạn quan tâm:

Ứng tuyển ngay it jobs for Developer lương cao tại đây

Hai kiểu lập trình viên

Hai kiểu lập trình viên

Bài viết được sự cho phép của tác giả Huy Trần

Luôn có hai dạng lập trình viên, một dạng luôn nắm vững lý thuyết, dạng còn lại thì không.

Những người nắm vững lý thuyết thì luôn có năng suất làm việc cao hơn hẳn những người không học lý thuyết, vì không phải tốn thời gian để thử sai (trial and error), cũng không cần tốn thời gian tra cứu lại kiến thức.

  10 câu nói cực hay về lập trình
  10 Kỹ năng quan trọng cần có của Front-end để tìm công việc dễ dàng hơn

Một ví dụ đơn giản về CSS, chúng ta có class .gift-image có thuộc tính top = 10px, và chúng ta muốn class này có thuộc tính top = 0 trên các thiết bị có màn hình nhỏ hơn 600px:

.gift-box {
    .gift-image {
        &.openned {
            position: absolute;
            top: 10px;
            ...
        }
    }
    
    @media (max-width: 600px) {
        .gift-image {
            top: 0;
        }
    }
}

Nhưng đoạn code trên sẽ không chạy, và trên mobile, class .gift-image vẫn có thuộc tính top = 10px.

Một frontend developer không nắm vững kiến thức sẽ fix vấn đề trên như sau:

@media (max-width: 600px) {
    .gift-image {
        top: 0 !important;
    }
}

Hoặc tốn 10 phút để search Google với một vấn đề không liên quan: position absolute top not change in media query.

Ngược lại, một frontend developer nắm vững kiến thức về CSS specificity [1] [2] sẽ fix vấn đề trên một cách dễ dàng mà không cần dùng tới !important:

@media (max-width: 600px) {
    .gift-image.openned {
        top: 0;
    }
}

Và thậm chí còn đạt tới cảnh giới code xong không cần test, sure đúng 100%, push lên thẳng master luôn, rồi để cho junior nó fix =)))

Ví dụ trên chưa có phần giải thích, để dành cho anh em đọc xong tự giải thích 

Đọc thêm:

  1. Calculating a selector’s specificity, https://www.w3.org/TR/selectors-3/#specificity 
  2. MDN CSS, Specificity, https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity 

Bài viết gốc được đăng tải tại thefullsnack.com

Có thể bạn quan tâm:

Truy cập ngay việc làm IT đãi ngộ tốt trên TopDev

Download, Export file tự động với Selenium Webdriver

Download, Export file tự động với Selenium Webdriver

Bài viết được sự cho phép của tác giả Tô Thị Vân Anh

Không biết viết mở đầu như thế nào, thôi thì đi thẳng vào vấn đề chính luôn cho nhanh. Bây giờ nếu muốn thực hiện tự động download file từ một trang web nào đó bằng Selenium thì chúng ta sẽ phải làm những gì và như thế nào?

  Các kiểu “đợi chờ” trong Selenium Webdriver: Implicit wait, Explicit wait và Fluent wait
  JavaScript Executor trong Selenium Webdriver

Download, Export file tự động với Selenium Webdriver

Đầu tiên mình sẽ đưa ra các bước mô phỏng được thực hiện trên trình duyệt Firefox như thế này nhé:

1. Mở trình duyệt Firefox và đi tới link có chứa thông tin file cần tải xuống

2. Nếu khi mở link trang web ra mà đã có chứa file cần download ở đó luôn rồi thì sang bước tiếp theo. Hoặc chưa có thì các bạn có thể thực hiện click vào menu nào đó để đi đến trang có thông tin download được là được nhé.

Download, Export file tự động với Selenium Webdriver

3. Thực hiện click vào link hoặc button để tải file xuống.

4. Lúc này, có 1 cửa sổ của hệ thống hiển thị ra có hỏi bạn là bạn muốn mở file này hay muốn lưu file này. Rất tiếc là bạn không thể sử dụng Selenium để thực hiện lựa chọn nào đó được, vì thế sẽ phải tìm cách xử lý cái popup này.

Download, Export file tự động với Selenium Webdriver

5. Cuối cùng, chờ file tải xong và đóng trình duyệt.

Thực tế thì chúng ta vẫn làm như vậy, còn để biến các bước này vào trong code và để nó làm được các công việc kia thì sẽ cần làm gì? Cũng rất đơn giản thôi.

Không tính các bước râu ria, không liên quan lắm đến chủ đề bài viết thì các bước cơ bản sẽ như sau:

1. Khởi tạo một profile cho FirefoxProfile.

FirefoxProfile profile=new FirefoxProfile();

2. Set Preference cho profile đó – Các preference cho từng loại file mà bạn muốn tải xuống, (có thể là file .Zip, .docx, .elsx, .pdf … ) tùy từng loại file mà bạn sẽ cần có các preference tương ứng. Và bạn cũng có thể lựa chọn thêm các Preference khác để có các tùy chọn cài đặt tương ứng, như mình đã giải thích ở bài trước. Ví dụ:

//set = 2 để lưu file vào một thư mục cụ thể nào đó trong máy tính của
profile.setPreference("browser.download.folderList", 2);

//Giá trị = false, không mở cửa sổ khi download
profile.setPreference("browser.download.manager.showWhenStarting", false);

// Set đường dẫn lưu file xuống máy tính
profile.setPreference("browser.download.dir", 
                                  "D:\\AnhTo\\Draft\\DownloadFile");
// Ở đây mình truyền vào các loại file liên quan đến bộ office thì nó sẽ không hỏi, mà lưu luôn xuống máy.
profile.setPreference("browser.helperApps.neverAsk.saveToDisk",
                     "text/csv,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");

3. Khởi tạo trình duyệt với profile đã tạo:

WebDriver driver=new FirefoxDriver(profile);

4. Đi đến link trang web có thông tin file cần tải xuống:

driver.get("http://toolsqa.com/automation-practice-form/");

5. Click nút Download để tải file xuống:

driver.findElement(By.linkText("Test File to Download")).click();

6. Chờ download xong rồi đóng trình duyệt lại thôi.

Thread.sleep(5000);
driver.close();

Các bạn có thể tham khảo code đầy đủ phía dưới này nhé:

package test;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;

public class vccb_download {
       public static void main(String[] args) throws InterruptedException {
             System.setProperty("webdriver.gecko.driver","D:\\AnhTo\\Setup\\Wed_driver\\geckodriver.exe");         
             FirefoxProfile profile = new FirefoxProfile();         
             profile.setPreference("browser.download.folderList", 2);
             profile.setPreference("browser.download.manager.showWhenStarting", false);
             profile.setPreference("browser.download.dir", "D:\\AnhTo\\Draft\\DownloadFile");
             profile.setPreference("browser.helperApps.neverAsk.saveToDisk",
                           "text/csv,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");     
             FirefoxDriver driver = new FirefoxDriver(profile);       
             driver.get("http://toolsqa.com/automation-practice-form/");          
             driver.findElement(By.linkText("Test File to Download")).click();           
             Thread.sleep(5000);
             driver.close();
       }
}

Khá là đơn giản đúng không nào 😀 Đã định nói thêm cái gì đấy mà nghĩ mãi không nhớ ra là cái gì, thôi thì tạm thế đã nhé. Hehe

Chúc các bạn tuần mới và có kỳ nghỉ lễ vui vẻ! Mình đi nghỉ lễ sớm đây. hiiiiii

Bài viết gốc được đăng tải tại vananhtooo.wordpress.com

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Hướng dẫn cách cài đặt VMware Workstation trên Ubuntu

Hướng dẫn cách cài đặt VMware Workstation trên Ubuntu

Bài viết được sự cho phép của tác giả Kiên Nguyễn

Chào các bạn, kể từ khi công nghệ ảo hóa ra đời thì nó đã giúp chúng ta rất nhiều trong việc giảm thiểu chi phí đầu tư cho các thiết bị cơ sở hạ tầng, kiểm thử phần mềm và nhiều những ưu điểm tuyệt vời khác.

Đơn cử như việc bạn có thể tạo ra một hoặc nhiều máy tính ảo chạy trên một máy tính thật, mà chức năng của các máy ảo đó tương tự như máy thật. Và tất nhiên, các máy ảo này khi chạy thì cũng sẽ chiếm tài nguyên phần cứng của máy thật.

  Chạy file jar giống như một service trên Ubuntu (Linux)
  Sếp nhớ trả lương em gấp 10 nha (phần 2) - HĐH Ubuntu

Hiện nay có rất nhiều công cụ hỗ trợ việc ảo hóa như vậy. Tiêu biểu nhất có thể kể đến như: VirtualBox, VMware, Parallels… Trong số này có VirtualBox là miễn phí còn lại hầu như đều phải trả phí.

Để tìm hiểu kỹ hơn về các phần mềm này, và hiểu hơn về tác dụng của phần mềm ảo hóa thì bạn có thể tham khảo các bài viết sau:

Trong bài viết này mình sẽ hướng dẫn các bạn cách cài đặt VMware trên Ubuntu (một trong những phần mềm tạo máy tính ảo tốt nhất và phổ biến nhất hiện nay). Ok, giờ thì bắt đầu thôi nào !

Cài đặt VMware Workstation trên Ubuntu

+ Bước 1: Đầu tiên, các bạn hãy truy cập vào đường link bên dưới để download file cài đặt phần mềm VMware về, các bạn lưu ý chọn đúng phiên bản cho hệ điều hành Linux nha.

https://www.vmware.com/products/workstation-pro/workstation-pro-evaluation.html

Hướng dẫn cách cài đặt VMware Workstation trên Ubuntu

+ Bước 2: Sau đó các bạn bật công cụ dòng lệnh Terminal lên bằng cách nhấn tổ hợp phím CTRL + ALT  + T => và chạy cho mình lệnh sau:

sudo apt install build-essential

Hướng dẫn cách cài đặt VMware Workstation trên Ubuntu

+ Bước 3: Sau đó, các bạn di chuyển tới thư mục có chứa file cài đặt mà các bạn download về. Ở đây mình đang để nó ngoài Desktop và có tên là:

VMware-Workstation-Full-16.1.0-17198959.x86_64.bundle

NOTE: Các bạn có thể đổi tên tùy ý nha. Bạn có thể đổi tên file này cho dễ gõ lệnh hơn nhé. Ví dụ abc.bundle. Còn ở đây mình giữ nguyên tên file nhé !

+ Bước 4: Tiếp theo các bạn chạy lệnh sau:

sudo bash <filename> như hình bên dưới và nhấn Enter..

Áp dụng vào ví dụ này là: sudo bash VMware-Workstation-Full-16.1.0-17198959.x86_64.bundle

Nếu sau khi chạy 100% mà hiện lên thông báo Installation was successful như hình bên dưới thì tức là bạn đã cài đặt thành công rồi nhé.

Hướng dẫn cách cài đặt VMware Workstation trên Ubuntu

+ Bước 5: Sau đó các bạn vào kho ứng dụng đã cài đặt, tìm kiếm với từ khóa VM thì kết quả sẽ xuất hiện như hình bên dưới. Các bạn bấm vào VMware Workstation để bắt đầu một số công việc cấu hình.

Hướng dẫn cách cài đặt VMware Workstation trên Ubuntu

Ở bước này các bạn tích vào I accept terms in the license agreement => sau đó bấm Next để tiếp tục.

NOTE: Ở đây các bạn phải cuộn hết cái License Agreement để đồng ý với điều khoản của họ thì mới bấm Next được nha. Để xác nhận là bạn đã đọc hết rồi ấy mà 🙂

Hướng dẫn cách cài đặt VMware Workstation trên Ubuntu

+ Bước 6: Tiếp theo các bạn cứ chọn như trong hình => rồi bấm Next thôi.

Hướng dẫn cách cài đặt VMware Workstation trên Ubuntu

Tiếp tục chọn theo như hình bên dưới rồi bấm Next.

Hướng dẫn cách cài đặt VMware Workstation trên Ubuntu

+ Bước 7: Ở bước này, nếu có yêu cầu quyền quản trị thì bạn nhập mật khẩu máy khi các bạn Ubuntu hoặc các hệ điều hành tương ứng.

=> Sau đó bấm Enter hoặc bấm vào Authentication để bắt đầu xác nhận.

Hướng dẫn cách cài đặt VMware Workstation trên Ubuntu

Và đây là giao diện của phần mềm VMware Workstation trên Ubuntu. Vì VMware Workstation là phiên bản trả phí nên bạn chỉ có quyền dùng thử 30 ngày, tính từ ngày cài đặt.

Sau đó, nếu bạn muốn dùng tiếp bạn phải mua bản quyền thì mới có thể tiếp tục sử dụng được.

Mình nghĩ 30 ngày là khoảng thời gian đủ để bạn trải nghiệm và đưa ra quyết định có nên mua thêm hay không. Khi mua bạn sẽ được cấp key và bạn sẽ dùng key đó để sử dụng phần mềm.

GỢI Ý: Bạn có thể sử dụng thẻ MasterCard ảo để thanh toán Quốc tế một cách dễ dàng.

Hướng dẫn cách cài đặt VMware Workstation trên Ubuntu

Lời Kết

Vậy là trong bài viết mình đã hướng dẫn các bạn cách cài đặt VMware Workstation trên hệ điều hành Ubuntu phiên bản 20.04 rồi ha. Các phiên bản mới hơn thì các bạn cũng làm hoàn toàn tương tự vậy thôi, không khác gì cả.

Trong các bài viết tiếp theo mình sẽ hướng dẫn các bạn cách thiết lập cũng như cài đặt máy ảo bằng cách sử dụng VMware Workstation. Hẹn gặp lại các bạn trong các bài viết tiếp theo nha !

CTV: Nguyễn Đức Cảnh – Bài viết gốc tại blogchiasekienthuc.com

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Optical Character Recognition (OCR) – Nhận diện ký tự từ ảnh

Optical Character Recognition (OCR) – Nhận diện ký tự từ ảnh

Bài viết được sự cho phép của vntesters.com

Trong ví dụ này mình sẽ có input là một tấm ảnh chụp từ màn hình mobile, kết quả output mong muốn sẽ là nội dung chữ trên bức ảnh đó và kiểm tra lại để đảm bảo trên ảnh có chứa những nội dung chữ mình mong muốn.

  Trải nghiệm công nghệ nhận diện gương mặt ngay tại Vietnam Mobile Day, bạn đã thử chưa !
  "Muốn đi nhanh phải dựa vào dev, muốn đi nhanh hơn nữa phải dựa vào khách hàng"

Optical character recognition (also optical character reader, OCR) is the mechanical or electronic conversion of images of typed, handwritten or printed text into machine-encoded text, whether from a scanned document, a photo of a document, a scene-photo (for example the text on signs and billboards in a landscape photo) or from subtitle text superimposed on an image.

Optical Character Recognition (OCR) – Nhận diện ký tự từ ảnh

OCR Input (PNG file): Screenshot_2017-03-15-14-57-02.png
OCR Output (text): The text “Logs saved to sdcard/SysLog/2017-03-15_14.56.59

Các bước thực hiện:
1. Bạn có thể tạo một project mới hoặc tải project mẫu mình đã upload tại đây.
2. Import thư viện Tess4J và các thư viên liên quan (có thể import hết thư viện trong thư mục “tesslibs” mình để trong project).
3. Đặt thư mục “tessdata” (data dùng để nhận diện ký tự) và hình ảnh cần test ra thư mục root, sau này bạn có thể thay đổi đường dẫn đến hình ảnh cũng được.

Optical Character Recognition (OCR) – Nhận diện ký tự từ ảnh

Sau khi có đủ thư viện, đặt thư mục tessdata và hình ảnh input đúng vị trí, chúng ta tạo một class mới để bắt đầu. Đây là một đoạn code ngắn để thực hiện những yêu cầu ban đầu:
1. Đọc chữ từ screenshot.
2. In tất cả các chữ có trên ảnh ra.
3. Kiểm tra những chữ đã xuất ra được có chứa các nội dung mình cần hay không.

package Tess4J;
import java.io.File;

import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.Tesseract;

public class ReadText {

public static void main(String[] args) {
// Set the image source path
String imagePath = “Screenshot_2017-03-15-14-57-02.png”;

File image = new File(imagePath);
// JNA Interface Mapping
ITesseract instance = new Tesseract();
try {
String Textresult = instance.doOCR(image);
// Print out the text results
System.out.println(Textresult);

// Verify to check the text is displayed
System.out.println(“**************”);
String ExpectedText = “Logs saved to sdcard/SysLog/”;

if (Textresult.contains(ExpectedText)) {
System.out.println(“Passed. The expected text is displayed!”);
} else {
System.out.println(“Failed. The text was not found!”);
}

} catch (Exception e) {
System.out.println(“Failed. Could not read the text from image file!”);
}
}
}

Nội dung chúng ta có được:

Optical Character Recognition (OCR) – Nhận diện ký tự từ ảnh

Cách này khá hữu ích khi làm automation, đôi lúc có những thành phần không thể getText do không lấy được locators, dùng cách này thì chúng ta sẽ không cần locators, ngoài ra còn ứng dụng trong các trường hợp khác như đọc nội dung PDF, tài liệu scanned. Các bạn thử nhé!

Bài viết gốc được đăng tải tại vntesters.com

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Web storage là gì?

Web storage là gì

Bài viết được sự cho phép của tác giả Lê Chí Dũng

HTML Web Storage là gì?

HTML Web Storage là tính năng mới của HTML5.

HTML Web Storage được tạo ra để lưu trữ data của user ở dưới local giống như cookie.

HTML Web Storage và Cookie khác nhau như thế nào ? Tại sao nên dùng HTML Web Storage ?

Cookie là một đoạn văn bản ghi thông tin được tạo ra và lưu trên trình duyệt của máy người dùng. Cookie thường được tạo ra khi người dùng truy cập một website. Cookie sẽ ghi nhớ những thông tin như tên đăng nhập, mật khẩu, các tuỳ chọn do người dùng lựa chọn đi kèm… Các thông tin này được lưu trong máy tính để nhận biết người dùng khi truy cập vào một trang web. Tuy vậy, cookie có một số khuyết điểm như:

Cookie luôn luôn gửi request tới web server vì vậy đối với các tệp lớn thì nó có thể tiêu tốn băng thông đáng kể.

Giới hạn của một cookie chỉ là 4 KB.

Người dùng có thể mở file chứa cookie và sửa nội dung trong đó.

Trong một số trường hợp người dùng disable cookie trên trình duyệt thì tính năng này sẽ bị vô hiệu hóa.

Có lẽ vì những khuyết điểm đó mà HTML Web Storage được sinh ra.

Ưu điểm của HTML Web Storage :

Web storage là gì?

HTML Web Storage có thể lưu trữ một lượng data lớn từ 2MB tới 10MB. Giới hạn này phụ thuộc vào browser, protocol (HTTP hoặc HTTPS).

  • Web Storage an toàn hơn: người dúng khó mà có thể tìm ra file lưu Web Storage để sửa data. Tuy vậy thì chúng ta vẫn có thể sửa data Web Storage khi F12 trên trình duyệt.
  • Web Storage cũng lưu trữ ở dưới local nhưng nó không bao giờ được gửi tới web server vì vậy mà không ảnh hưởng tới băng thông.
  • Data được lưu trữ trên một trình duyệt nên không thể truy xuất trên trình duyệt khác.
  • Data được lưu trữ dưới dạng chuỗi JSON.
  • Web Storage là tính năng của HTML5 nhưng nó hỗ trợ đến cả những phiên bản trình duyệt cũ mà hiện tại ít ai dùng.

Web storage là gì?

Ứng dụng của Web Storage

  • Dùng để lưu những data của user mà được sử dụng nhiều lần trên các phiên làm việc khác nhau (một phiên làm việc được tính là một lần đóng mở tab).
  • Dùng cho các ứng dụng SPA ( Single page application). Thông thường khi xử lí dữ liệu thao tác của user trên 1 page thì chúng ta lưu vào biến javascript. Còn nếu muốn share dữ liệu giữa các page thì có thể dùng Web Storage. Ví dụ lưu thông tin đăng nhập của user, lưu thông tin giỏ hàng, …
  • Không dùng Web Storage để lưu các dữ liệu quan trọng như mật khẩu người dùng, …

Làm việc với web storage

Có 2 loại storage:

  • localStorage – dữ liệu được lưu mãi mãi kể cả khi đóng tab hoặc đóng trình duyêt. Dữ liệu chỉ mất khi clear history.
  • sessionStorage – dữ liệu được lưu trong 1 phiên làm việc. Dữ liệu mất khi người dùng đóng tab.

Kiểm tra trình duyệt có hỗ trợ storage không

if (Storage) {
// Storage is supported!
} else {
// No support. Use a fallback such as browser cookies or store on the server.
}

Lưu Data:

// Functions
localStorage.setItem(‘name’, ‘Matt West’);

// Object
localStorage.name = ‘Matt West’;

// Array
localStorage[‘name’] = ‘Matt West’;

Dữ liệu được lưu dưới dạng key:value. Tùy vào dữ liệu mà chúng ta có các cách lưu khác nhau. Với dữ liệu đơn giản thì lưu key value như một chuỗi đơn giản. Với dữ liệu phức tạp thì nên lưu value dưới dạng chuỗi JSON, khi lưu dữ liệu dùng JSON.stringify() còn khí lấy dữ liệu dùng JSON.parse(). Vì dữ liệu được lưu dưới dạng string nên khi lấy ra có thể cần phải xử lí bằng cách dùng các hàm parseInt(), parseFloat(), …

Lấy Data

localStorage.getItem(‘name’);
localStorage.name
localStorage[‘name’]
Xóa Data
localStorage.removeItem(‘name’);
localStorage.clear();
Event
window.addEventListener(“storage”, function(event) {
var key = event.key;
var newValue = event.newValue;
var oldValue = event.oldValue;
var url = event.url;
var storageArea = event.storageArea;

// handle the event
});

Bài viết gốc được đăng tải tại lcdung.top

Có thể bạn quan tâm:

Xem thêm IT Jobs for Developer hấp dẫn trên TopDev

Google Assistant | Interactive Game gồm những công nghệ gì? Hướng dẫn xây dựng một Interactive Game

Các Interactive Game bên trong trợ lý ảo Google Assistant được xây dựng như thế nào và Google đã ứng dụng những công nghệ gì bên trong. Bài viết sẽ giúp bạn giải đáp thắc mắc trên đồng thời hướng dẫn cách xây dựng một Interactive Game cho trợ lý ảo Google. 

Nội dung này được trình bày bởi Ms. Mandy Chan – Developer Advocate @Google. Qua bài chia sẻ, bạn sẽ hiểu thêm về:

  • Khái niệm Conversational Action (tạm dịch: Hành động hội thoại)
  • Khái niệm Interactive Canvas API
  • Cách để xây dựng một full-screen interactive game trên Android với JavaScript

Tại sao bạn nên xây dựng Interactive Game trong Google Assistant

Hiện tại, Google Assistant đang hỗ trợ hơn 19 ngôn ngữ và hoạt động trên 80 quốc gia. Dù người dùng mục tiêu của bạn ở bất kỳ đâu, Google Assistant đều có thể giúp đỡ họ thông qua hơn 1 tỷ thiết bị đang sử dụng ứng dụng này. Bạn có thể tiếp cận họ theo nhiều cách khác nhau thông qua Google Assistant.

Người dùng hiện tại đang sử dụng các thiết bị thông minh theo nhiều cách khác nhau. Theo nghiên cứu được thực hiện bởi Adobe, phần lớn người dùng sử dụng các thiết bị thông minh nhằm phục vụ cho nhu cầu âm nhạc và cho các hoạt động thường nhật, chẳng hạn như cập nhật thông tin thời tiết. Đồng thời, cũng có một lượng lớn người dùng sử dụng các thiết bị để giải trí, chơi game.

Trong số những người sử dụng Google Assistant, có 55% người dùng sử dụng cô trợ lý ảo này chỉ để hỏi những câu hỏi vui; có 20% thì sử dụng để chơi các trò chơi bên trong ứng dụng Google Assistant (*Google gọi đây là Interactive Game).

Giờ hãy cùng đi vào nội dung chi tiết.

Interactive Game là gì?

Smart display lần đầu ra mắt vào năm 2019. Trong suốt năm đó, số lượng người dùng tương tác với các thiết bị smart display đã tăng lên gấp 4 lần.

Từ hai năm trước, chúng ta đã thấy được sức hút của các trò chơi bằng giọng nói (voice game) bên trong trợ lý ảo Google Assistant.

Các lập trình viên đã tạo ra những ứng dụng mang tính tương tác cao như thế bằng cách tận dụng thứ mà Google Assistant làm tốt nhất. Đó là “cô ấy” có thể hiểu được giọng nói và ngôn ngữ của người dùng.

Kết quả là voice game đã rất thành công trong việc tạo ra một trải nghiệm tốt cho người dùng trong một môi trường chỉ có mỗi audio.

Ngày nay, nhờ sự phổ biến của smart display, nhiều lập trình viên cũng bắt đầu xây dựng các trò chơi có thể tương tác cả giọng nói lẫn hình ảnh, chẳng hạn như các tựa game: Guess the Drawing, Trivia Crack, Who wants to be a Millionaire,…

Với Guess the Drawing, bạn có thể chơi game với hàng trăm bức ảnh động đầy hấp dẫn ở chế độ xem chậm. Trong khi đó, nhờ Trivia Crack, bạn có thể chơi game mà vẫn có thêm kiến thức với bộ câu hỏi và câu trả lời về các chủ đề như lịch sử, mỹ thuật, giải trí và khoa học. Với Who wants to be a Millionaire, người tham gia sẽ trả lời một bộ câu hỏi để chinh phục mức giải thưởng cao nhất là 1 triệu USD, đồng thời bạn cũng có thể sử dụng các quyền trợ giúp để tham gia cuộc chơi này.

Và đây là một tựa game khác: “Are You Feeling Lucky?”

Interactive Game này sử dụng cả lợi thế của việc hiển thị trên màn hình lẫn tương tác bằng giọng nói của Google Assistant.

Nhiều người chơi sẽ cùng nhau tham gia trả lời các câu hỏi đơn giản được đưa ra và trên màn hình sẽ hiển thị các avatar khác nhau để giúp phân biệt và theo dõi xem đang đến lượt của người chơi nào.

Những hình ảnh động này có thể được tạo ra là nhờ một thứ được gọi là Interactive Canvas.

Ứng tuyển ngay các vị trí tuyển dụng lập trình Game lương cao trên TopDev

Interactive Canvas là gì? Hoạt động như thế nào?

Interactive Canvas là gì?

Interactive Canvas là một API cho phép các lập trình viên tạo ra fluid animation (một loại hiệu ứng chuyển động) và customize trò chơi của họ bằng cách sử dụng các công nghệ quen thuộc như HTML, CSS, JavaScript và Web Assembly.

Nhờ kết hợp giữa các khả năng hiển thị (visual capabilities) cùng với khả năng hiểu biết ngôn ngữ tự nhiên và nhận diện giọng nói của Google, các lập trình viên giờ đây có thể thỏa sức sáng tạo của bản thân thông qua việc xây dựng các Interactive Game trên Google Assistant với cả các hiệu ứng hình ảnh, chuyển động lẫn âm thanh.

Interactive Canvas hoạt động như thế nào?

Trước khi đào sâu vào Interactive Canvas, hãy cùng tìm hiểu về cách vận hành (diagram) của một Hành động (action) diễn ra với action builder/ SDK và một web service.

Lifecycle của một Conversational Action

Web service có thể được sử dụng để cung cấp dynamic prompts và làm cho API gọi vào hoặc kiểm tra bên trong database.

Web service yêu cầu thiết bị tìm nạp (fetch) web app

Khi người dùng nói chuyện với thiết bị, giả dụ: “Ok Google, talk to my conversational action”, thiết bị sẽ gửi đoạn audio những gì người dùng đã nói tới action. Action ngay sau đó tiến hành xử lý request trả về một prompt web service của bạn. Nó bao gồm các dữ liệu như canvas, web app và các metadata khác.

Khi thiết bị nhận được những thứ này, nó sẽ khởi tạo web app của bạn.

Bên trong web app, Interactive Canvas API được khởi tạo và sau đó website được render trên thiết bị.

Bởi do người dùng tương tác với action của bạn, bạn có thể update và request dữ liệu giữa server và bên client. Đây cũng là một high-level và nó có thể diễn ra.

Code: Fulfillment và Web App logic

Hiện tại, Canvas đang hỗ trợ trên các thiết bị smart display và điện thoại android. Điều này có nghĩa là trước khi bạn gửi đi một canvas response, hãy kiểm tra thiết bị của phía client xem nó có hỗ trợ canvas không. Chúng ta thực hiện nó bằng cách kiểm tra trên thiết bị (device capabilities) xem có bao gồm interactive canvas không, bằng cách tìm:

Surface capability:

conv.device.capabilities.includes(‘INTERATIVE_CANVAS‘)

Đến phần tải lên canvas web app, bạn sẽ cần sử dụng một lớp (class) canvas mới, được cung cấp bởi node.js trong thư viện của bên phía client. Class này có 2 thuộc tính (properties) gồm: url và data.

Hãy luôn nhớ rằng lần đầu tiên mà bạn gửi lại canvas response, NÓ BUỘC PHẢI CÓ MỘT URL. Nó sẽ giúp cho thiết bị biết đâu là nơi để tìm nạp (fetch) web app.

Hãy luôn nhớ rằng lần đầu tiên mà bạn gửi lại canvas response, nó buộc phải có một URL.

Một điều cần lưu ý nữa là hãy đảm bảo URL đấy là https để chắc chắn hoạt động một cách bảo mật.

Điều gì sẽ xảy ra ở phía client sau khi nhận được canvas response?

  • Web app là 1 trang web được render trên thiết bị.
  • Nó được build chủ yếu bằng hai công nghệ web truyền thống là HTML JavaScript.
  • Khi web app được tải thì cũng đồng thời khởi tạo Canvas JavaScript library. Đây là một client-side library vận hành trên thiết bị. Đừng nhầm lẫn nó với server-side node.js client library.
  • Canvas JavaScript xử lý response từ phía server và nó cũng tạo ra các request tới thiết bị.
  • Một lưu ý nhỏ đó là bạn cũng có thể build web app bằng cách sử dụng các JavaScript framework phổ biến như React hay tất cả các libraries như pixie.js.
  • Thêm nữa, bạn nên sử dụng Single Page Application (SPA) vì nó giúp tránh được tình trạng nhấp nháy như website và đảm bảo một UI mượt mà cho người dùng mobile.

SPA-in-Interactive-Games

Loading process trên thiết bị là một phần của web app. Interactive Canvas Library được nhập vào và được khởi tạo. Sau khi đã được khởi tạo, bạn có thể truy cập vào một thể hiện (instance) của interactive canvas – thứ cho phép bạn kiểm soát canvas response thông qua việc sử dụng on update callback. Gửi các request tới server bằng cách sử dụng the send text query method. Interactive canvas instance cũng cho phép bạn đăng ký callbacks thông qua ready method.

Việc gửi requests từ client đến server được thực hiện như thế nào?

Chúng ta đã trao đổi về cách để kiểm soát canvas response từ phía server của client. Vậy còn về việc gửi requests từ client đến server? Điều này có thể được thực hiện bằng cách gọi send text query method trên interactive canvas object.

SendTextQuery mang một StringValue – một cụm từ (phrase) mà người dùng sẽ nói một cách khác là để trigger chính xác intent. Đây là một method mạnh mẽ để giao tiếp với server và chúng ta sẽ cùng nhau xem qua một vài dòng code để dễ hình dung hơn.

Các nguyên tắc khi thiết kế Interactive Game (Design Principles)

Chúng ta đã làm việc với nhau về Interactive Canvas là gì, cách mà client và server tương tác với nhau và cách chúng ta duy trì trạng thái (state) giữa server và client. Giờ hãy cùng tìm hiểu về design principles ở phần xây dựng Interactive Game cho Google Assistant.

Chuyển tiếp giọng nói

Khi build một Interactive Game, hãy đảm bảo rằng nó mang tính đối thoại (conversational) thay vì ở dạng lệnh (command-based). Hãy nghĩ về những điều này từ ngay khi trò chơi được bắt đầu.

Tận dụng hiệu ứng hình ảnh

Việc tận dụng hình ảnh khi xây dựng các trò chơi cho smart display rất quan trọng. Hãy đảm bảo rằng:

  • Bạn mang đến người dùng những dấu hiệu trực quan (visual cue).
  • Làm nổi bật các item có thể  tương tác trên màn hình.
  • Sử dụng các hình ảnh chuyển động để hiển thị cho người dùng các điểm chính cần quan tâm (point of interest).

Tối ưu hiển thị

Tối ưu hóa hiển thị và thiết kế giao diện cũng là một phần quan trọng. Sử dụng kích thước phông chữ tối thiểu là 32pt cho văn bản chính như tiêu đề và kích thước 24pt cho văn bản phụ như đoạn mô tả hay các đoạn văn bổ sung được xem là lựa chọn hợp lý.

Chế độ nhiều người chơi cục bộ

Đối với các trò chơi nhiều người chơi, tận dụng lợi thế của việc có thể hiển thị để thể hiện các lượt chơi của các người chơi bằng cách sử dụng các icon khác nhau.

Xử lý lỗi

Cũng giống như những công việc khác, hãy nhớ kiểm soát các lỗi trong trò chơi một cách khéo léo. Một mẹo để làm việc này đó là sử dụng các gợi ý ở dạng hình ảnh / văn bản hay âm thanh rõ ràng khi người dùng gặp rắc rối trong trò chơi. 

Tận dụng SSML và thư viện âm thanh được cung cấp bởi Google

Để cải thiện trò chơi hơn, bạn có thể tận dụng thêm công nghệ SSML và thư viện âm thanh của Google. SSML hay còn được gọi là Speech Synthesis Markup Language. Nếu bạn là một web developer thì có thể hiểu SSML cũng tương tự CSS. Với CSS, bạn có thể thiết kế style cho văn bản thì SSML sẽ giúp bạn thiết kế style cho giọng nói (voice) bằng cách thay đổi âm lượng, cao độ giọng nói, thậm chí thêm vào các quãng ngắt nghỉ giữa các từ. Đồng thời, SSML cũng cho phép bạn thêm vào phân lớp (layering) của âm thanh vào background.

**Tìm hiểu thêm về Parallel Media Tag bằng link dưới đây: https://developers.google.com/assistant/conversational/ssml

**Sound Library hiện nay cũng là một open source được cung cấp bởi Google mà bạn có thể tận dụng: https://developers.google.com/assistant/tools/sound-library

Hiện đang có những loại games nào được build?

World Games được sáng tạo dưới dạng các câu hỏi đố và người chơi có thể trả lời trực tiếp bằng giọng nói.

Multiplayer Games là các loại game cho phép nhiều người chơi cùng lúc hiện cũng đang được phát triển khá phổ biến.

Persistent Games cho phép các người chơi chơi nối tiếp nhau một cách liên tục và được xây dựng dựa trên tình hình thực tế của mỗi khu vực, mỗi quốc gia.

Trên đây là giới thiệu một cách tổng quan về tất cả những gì có thể làm để phát triển game với Google Assistant. Hãy tự cởi bỏ giới hạn của bản thân và sáng tạo thêm thật nhiều những games hấp dẫn nhất.

Bài viết được trích dẫn từ phần trình bày của cô Mandy Chan – Developer Advocate @Google tại sự kiện Vietnam Web Summit 2020 LIVE do TopDev tổ chức

Xem ngay những tin đăng tuyển dụng IT mới nhất trên TopDev

Hướng dẫn sử dụng Mixins trong SASS toàn tập

Hướng dẫn sử dụng Mixins trong SASS toàn tập

Bài viết được sự cho phép của tác giả Trần Anh Tuấn

Chắc hẳn nhiều bạn trong khi học hay khi đi làm ở công ty sau khi vượt qua ngưỡng newbie về HTML hay là CSS rồi. Trong quá trình code CSS sẽ thấy rằng sao có nhiều người họ code cái template đó nhanh thế nhỉ ?

Sao mình cũng dùng CSS như họ mà, hay là mình gõ chậm nhỉ, hay là tư duy phân tích yếu. Thế là mò mẫm trên mạng và thấy người ta bảo dùng SASS code lẹ lắm, chẳng biết SASS là cái gì thế là vội vàng ngồi nghiên cứu về nó.

  Xây dựng một bộ source SASS thế nào cho đẹp
  Sử dụng Laravel Mix với Webpack cho tất cả các assets

Rồi phát hiện ra rằng CSS viết lồng nhau được luôn hay thật. Thế là cắm đầu cắm cổ tập viết lồng nhau bao nhanh luôn. Nhưng kết quả vẫn đâu vào đấy vẫn thấy chưa nhanh lắm, thế là tiếp tục hỏi cộng đồng mạng, và họ bảo dùng Mixins code cho nhanh

@mixin size($width, $height: $width) {
width: $width;
height: $height;
}

Và thấy dòng code trên rồi tự hỏi@mixin là cái gì thế nhỉ ? Rồi lại tiếp tục vọc tiếp và thấy rằng ah thì ra @mixin là như vậy nè nó giúp cho chúng ta có thể tái sử dụng và tận dụng code một cách triệt để, để đỡ phải gõ đi gõ lại một dòng code hoài, tiết kiệm thời gian và hoàn thành sớm nữa.

Vậy Mixins thực chất là gì ? Và làm sao để tạo một Mixin để sử dụng cho hiệu quả trong quá trình code trang web đây ?

Hiểu được nhu cầu của các bạn nên hôm nay mình viết bài này để chúng ta sẽ cùng nhau tìm hiểu về Mixins trong SASS là gì và một số hàm Mixins thông dụng trong SASS mà chúng ta nên biết để việc code được nhanh hơn nhiều nhé.

# Mixins là cái gì ?

Nếu các bạn làm lập trình thì chắc hẳn cũng biết đến function nhỉ ? Mixins cũng tương tự như vậy đấy. Nó cho phép chúng ta sử dụng đi sử dụng lại ở nơi nào mà chúng ta muốn hoặc ta có thể tùy chỉnh tham số truyền vào. Mục đích là tiết kiệm code, thời gian và đem lại hiệu quả cao.

Như đã nói Mixins cũng tương tự như function nên Mixins có 2 loại đó chính là

Loại có tham số

DÀNH CHO BẠN:

Mình có khoá học HTML CSS từ cơ bản tới nâng cao cho người mới, nếu bạn quan tâm thì bạn có thể học thử miễn phí bằng việc nhấn vào đây nha.

@mixin mixin_name(param1, param2...){
// code here
}

Loại không có tham số

@mixin mixin_name(){
// code here
}

Để gọi một Mixin ta có cú pháp như sau: @include mixin_name. Ví dụ

@mixin menulink(){
ul {
li {
display: inline-block;
a {
color: blue;
}
}
}
}
@include menulink;

Thì nó sẽ render như thế này

ul li {
display: inline-block;
}
ul li a {
color: blue;
}

# Một số hàm Mixins hay và thông dụng

Sau đây mình xin chia sẻ một số Mixins mà mình đã từng làm cũng như học hỏi được từ những pro khác trên mạng. Mình sẽ viết ra đây kèm giải thích cho các bạn nhé.

@mixin size

Cho phép chúng ta thiết lập độ rộng và chiều cao của một phần tử bất kỳ khi dùng.

@mixin size($width, $height: $width) {
width: $width;
height: $height;
}

Ví dụ mình muốn cho một class .box nào đó có chiều cao 100px và chiều rộng 100px mình sẽ dùng như thế này: @include size(100px), hàm ở trên mình set giá trị $height là mặc định nếu không truyền tham số thứ 2 thì nó sẽ bằng chiều rộng

Còn các bạn muốn set chiều rộng và chiều cao khác nhau thì các bạn có thể dùng như thế này: @include size(100px, 200px). Từ đó ta sẽ có kết quả

.box {
@include size(100px, 200px);
}
// result
.box {
width: 100px;
height: 200px;
}
@mixin box-shadow

Đúng như tên gọi mixin này cho phép chúng ta tạo box-shadow nhanh chóng. Có thể dùng box-shadow bình thường hoặc inset dựa vào các tham số truyền vào

@mixin box-shadow($top, $left, $blur, $color, $inset: false) {
@if $inset {
box-shadow:inset $top $left $blur $color;
} @else {
box-shadow: $top $left $blur $color;
}
}

Các bạn có thấy rằng giá trị mặc định của $inset nếu không truyền vào thì sẽ là false nên câu điều kiện @if sẽ chạy đoạn code ở dưới và ngược lại nếu là true thì sẽ chạy đoạn code trên. Sử dụng if else giống trong lập trình luôn.

.box{
@include box-shadow(10px,10px,20px,0px,true);
}
// result
.box {
box-shadow: inset 10px 10px 20px 0px;
}
@mixin transform

Cho phép tạo thuộc tính transform nhanh chóng dựa vào tham số chúng ta truyền vào

@mixin transform($property) {
-webkit-transform: $property;
-ms-transform: $property;
transform: $property;
}
.box { @include transform(rotate(30deg)); }
//result
.box{
-webkit-transform: rotate(30deg);
-ms-transform: rotate(30deg);
transform: rotate(30deg);
}
@mixin border-radius

Cho phép tạo border-radius cho phần tử chúng ta muốn, có thể set toàn bộ radius như nhau hoặc set từng góc có độ bo góc khác nhau nhé. Như ở dưới mình set các tham số tương ứng cho các góc.

@mixin border-radius($all: null, $tl: $all, $tr: $all, $btl: $all, $btr: $all) {
border-top-left-radius: $tl;
border-top-right-radius: $tr ;
border-bottom-right-radius: $btr;
border-bottom-left-radius: $btl;
}

Nếu mình chỉ điền vào một tham số đầu tiên thôi thì tất cả các tham số kia đều là tham số đầu từ đó ta có border-radius 4 góc đều như nhau. Tuy nhiên nếu các bạn muốn set riêng thì các bạn có thể dùng như thế này

.box{
@include border-radius(null, 2px, 3px, 4px, 5px);
}
// result
.box{
border-top-left-radius:2px;
border-top-right-radius: 3px ;
border-bottom-right-radius: 4px;
border-bottom-left-radius: 5px;
}

Các bạn có thể tối ưu hơn dựa vào những giải pháp khác nhé. Ở đây mình chỉ code đơn giản thôi, các bạn có thể suy nghĩ và làm nó tốt hơn nà

@mixin centerAbsolute

Khi các bạn code website sẽ gặp các trường hợp muốn làm một phần tử nào đó center bằng việc sử dụng thuộc tính position: absolute kết hợp với thuộc tính transform: translate đúng không ?

Thì trong một trang web dài hay nhiều layout phức tạp chắc chắn sẽ dùng nhiều, nên để tối ưu cho việc phải code đi code lại ta sẽ tạo ra một Mixin để sử dụng nó được nhiều nơi nhé

@mixin centerAbsolute($pos) {
position: absolute;
@if $pos == "both" {
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
} @else if $pos == "left" {
left: 50%;
transform: translateX(-50%);
} @else if $pos == "top" {
top: 50%;
transform: translateY(-50%);
}
}

Giả sử các bạn muốn phần tử .box đều center hàng dọc và ngang thì các bạn truyền tham số vào là both còn nếu chỉ muốn center hàng dọc thôi thì dùng top hoặc ngược lại muốn center theo chiều ngang thôi thì dùng left

.box{
@include centerAbsolute("both");
}
//result
.box{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}

Ngoài ra còn có nhiều Mixins hay khác mà các bạn có thể viết thêm như là khi viết media queries để làm responsive hay là hiển thị flexbox chẳng hạn.

@mixin min/max-width
@mixin minWidth($breakpoint) {
@media only screen and (min-width: $breakpoint) { @content; }
}
@mixin maxWidth($breakpoint) {
@media only screen and (max-width: $breakpoint) { @content; }
}

Thay vì các bạn phải viết đi viết lại dòng @media only screen dài quá thì mình viết một Mixin như trên để tiết kiệm thời gian các bạn có thể dùng nó như sau

.box{
@include minWidth(768px){
width: 200px;
height: 200px;
background-color: red;
}
}
//result
@media only screen and (min-width:768px){
.box{
width: 200px;
height: 200px;
background-color: red;
}
}
@mixin flexbox
@mixin flex($direction: row, $content: null , $items: null, $wrap: null) {
display: flex;
flex-direction: $direction;
justify-content: $content;
align-items: $items;
flex-wrap: $wrap;
}

Với các tham số truyền vào thì bạn tự do tùy chỉnh flexbox cho một phần tử mà bạn muốn một cách nhanh nhất nhé.

.box{
@include flex(row, center, center, wrap);
}
//result
.box{
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
flex-wrap: wrap;
}

Và còn còn rất nhiều Mixins hay và tuyệt vời hơn khác nữa, trong quá trình làm các bạn sẽ tự nhận ra nên viết những Mixins gì để tiết kiệm thời gian, nâng cao năng suất, giúp cho việc code trở nên khỏe hơn và mau hoàn thành hơn.

# Tạm kết

Hi vọng với những kiến thức về Mixins sẽ giúp ích cho các bạn phần nào trong quá trình code SASS được nhanh nhất nhé. Ngoài ra mình cũng tìm kiếm thêm trên Google và tìm được khá nhiều Mixins hay khác nữa mà các bạn có thể tham khảo tại đây hoặc tại đây nhé. Chúc các bạn một ngày tốt lành.

Bài viết gốc được đăng tải tại evondev.com

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Hướng dẫn cấu hình compiler MinGW, Cygwin cho Dev C++

Hướng dẫn cấu hình compiler MinGW, Cygwin cho Dev C++

Bài viết được sự cho phép của tác giả Trần Hữu Cương

Cấu hình compiler cho Dev C++

Dev C++ là một IDE, một phần mềm dùng để soạn thảo/ lập trình ngôn ngữ C/C++.

Trong bộ cài Dev C++ có tích hợp sẵn trình compiler C/C++ là Boost C++, tuy nhiên trình compiler này khá cũ hoặc đơn giản là máy bạn đã có sẵn trình compiler C/C++ nên bỏ qua không cài Boost C++.

Trong trường hợp này bạn cần phải cấu hình lại trình compiler trên Dev C++ để có thể thực hiện compile, run file C/C++.

  1001 Tips: Con trỏ và hàm (Pointer & Function) trong C++
  Các kiểu dữ liệu trong lập trình C/C++ (Data type)

Trên thanh menu chọn Tools/Compiler Options

Hướng dẫn cấu hình compiler MinGW, Cygwin cho Dev C++

Trong list Compiler set to configure sẽ hiển thị danh sách các compiler mà Dev C++ đang sử dụng

(Ở đây mình không cài Boost C++ nên list này đang bị trống)

Click vào button new thứ hai để trỏ tới folder cài trình biên dịch C/C++ trên máy bạn

Hướng dẫn cấu hình compiler MinGW, Cygwin cho Dev C++

Trên máy mình đang cài MinGW ở folder C:\MinGW 

Hướng dẫn cấu hình compiler MinGW, Cygwin cho Dev C++

Click OK, bạn sẽ thấy trình biên dịch MinGW hiển thị trong list Compiler set to configure 

(Như thế là bạn đã có thể compile và run file C/C++ trên Dev C++ với MinGW)

Hướng dẫn cấu hình compiler MinGW, Cygwin cho Dev C++

Để sử dụng Cygwin hay các trình biên dịch C/C++ khác thì các bạn làm tương tự như trên.

References:

https://stackoverflow.com/…/integrating-mingw-compiler-into-dev-c

Bài viết gốc được đăng tải tại codecute.com

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Cài đặt Spring Boot CLI

Cài đặt Spring Boot CLI

Bài viết được sự cho phép của tác giả Trần Thị Thu Hà

Bài viết sẽ hướng dẫn bạn cách cài đặt Spring Boot CLI phiên bản mới nhất (1.4.0.RELEASE tại thời điểm viết bài) trên Mac OS X (El Captain 10.11.6). Bạn download file này: http://repo.spring.io/release/org/springframework/boot/spring-boot-cli/1.4.0.RELEASE/spring-boot-cli-1.4.0.RELEASE-bin.tar.gz

  Giao tiếp Client / Server bằng gRPC
  Button Bootstrap: Cách tạo các loại button trong Bootstrap

THIẾT LẬP BIẾN MÔI TRƯỜNG

Sau đó giải nén, các tập tin cài đặt sẽ nằm trong thư mục spring-1.4.0.RELEASE . Mở file INSTALL.txt để xem hướng dẫn.

Giả sử, sau khi giải nén, thư mục chứa các tập tin cài đặt là:

/Users/donhuvy/Downloads/spring-1.4.0.RELEASE

thì bạn sẽ thiết lập biến môi trường như sau, gọi text editor Vim, sửa tập tin .bash_profile  bằng lệnh:

Gõ phím i để bắt đầu chế độ insert trong Vim, chèn thêm nội dung sau vào cuối tập tin:

Để lưu tập tin và thoát khỏi Vim, bạn gõ esc:wq!

Để kiểm tra chắc chắn nội dung mới đã ghi vào đúng cách, gõ lệnh:

Di chuyển đến cuối trang nội dung để thấy các nội dung thêm vào đã có. Để thoát khỏi lệnh tail, gõ control + C .

Để biến môi trường kể trên có hiệu lực, có 2 cách:

Cách 1: Gõ lệnh:

Cách 2: Đóng tất cả các cửa sổ Terminal, thoát Terminal, sau đó mở lại.

CÀI ĐẶT HỖ TRỢ AUTO-COMPLETE (khi gõ lệnh trong Spring Boot CLI)

Di chuyển đến thư mục chứa tập tin cài đặt (ở bước này, trên mỗi máy khác nhau có thể sẽ khác nhau):

Kiểm tra chính xác thư mục hiện tại:

Kiểm tra các tập tin trong gói cài đặt:

Tạo thư mục  /etc/bash_completion.d  bằng quyền của super admin:

Tạo thư mục  /usr/local/share/zsh/sitefunctions bằng quyền của super admin:

Tạo liên kết biểu tượng (symbolic link, trong Windows gọi là short-cut):

tương tự:

Hoàn thành xong bước này, Spring CLI đã hỗ trợ auto-complete.

Cài đặt Spring Boot CLI

KIỂM TRA KẾT QUẢ

Nếu thấy kết quả trả về là:

có nghĩa là quá trình cài đặt Spring Boot CLI đã thành công.

ỨNG DỤNG SPRING BOOT ĐẦU TIÊN

Kiểm tra thư mục hiện hành:

Tạo tập tin SmarjobWebController.java trong thư mục hiện hành:

Biên soạn nội dung tập tin:

Chạy ứng dụng:

Cài đặt Spring Boot CLI

Chúc mừng bạn, bạn vừa hoàn thành một ứng dụng Java web sử dụng Spring Framework, với sự hỗ trợ của Spring Boot (Source base này rất ổn định, là enterprise-class). Đây là cách làm rất nhanh, đặc sắc, chứng tỏ bạn am hiểu về Spring Boot khi khởi tạo cả một ứng dụng đồ sộ chỉ từ giao diện dòng lệnh (CLI: Command Line Interface).

Mẹo: Để thay đổi URL cho controller, hãy sửa giá trị mapping trong annotation @RequestMapping(“/your/prefer/url/path/foo/”)

Series bài viết chuyên sâu về Spring Framework đã được gắn tag: https://smartjob.vn/topic/spring-framework/

Bài viết gốc được đăng tải tại smartjob.vnĐỗ Như Vý

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Một vài pattern để viết component của React cần dùng chung state

Một vài pattern để viết component của React cần dùng chung state

Bài viết được sự cho phép của tác giả Lưu Bình An

compound component

Khi gặp tình huống một component không thể đứng độc lập, mà nó buộc phải kết hợp với một component khác và cùng chia sẻ một bộ state và phương thức. Đó là lúc chúng ta cân nhắc cách viết compound component.

Một ví dụ rất dễ thấy của compound component là element <select /> và <option /><option/> không thể đứng độc lập, nó luôn được đặt trong <select/> có thể truy xuất và gọi các phương thức tương tự như <select/>

Tìm việc làm lập trình viên React

Tại sao lại sử dụng compound component?

Nếu bạn là người viết component, người khác sử dụng component này, các dev khác sẽ cảm ơn bạn rất nhiều. Bạn đóng gói mọi thứ logic vào bên trong component cha như vậy, người sau sẽ không cần bận tâm nữa.

// parent component
// xử lý event onChange, quản lý state selected value
<RadioImageForm>
	<RadioImageForm.RadioInput />
	<RadioImageForm.RadioInput />
	<RadioImageForm.RadioInput />
</RadioImageForm>

Với child component của <RadioImageForm />, để cho nó rõ ràng minh bạch là chúng ta sẽ sử dụng những giá trị cung cấp từ parent, chúng ta dùng kiểu viết <RadioImageForm.RadioInput />

export class RadioImageForm extends React.Component<Props, State> {
	static RadioInput = ({
		currentValue,
	    onChange,
	    label,
	    value,
	    name,
	    imgSrc,
	    key,
	}: RadioInputProps): React.ReactElement => (
		// ...
	);
	onChange = (): void => {
	  // ...
	};

  state = {
    currentValue: '',
    onChange: this.onChange,
    defaultValue: this.props.defaultValue || '',
  };

  render(): React.ReactElement {
    return (
      <RadioImageFormWrapper>
        <form>
        {/* .... */}
        </form>
      </RadioImageFormWrapper>
    )
  }
}

Một nhu cầu rất phổ biến là người khác sẽ muốn control component con <RadioInput /> bằng việc truyền thêm prop, nhưng thay vì truyền thằng vào component con, chúng ta hãy để họ truyền thông qua component cha <RadioImageForm/>, vì một lý do nào đó chúng ta cần truy cập các prop này bên trong component cha thì sao? Chúng ta làm thêm một bước pass-through các prop xuống cho component con với React.Children.map hoặc React.cloneElement

render(): React.ReactElement {
  const { currentValue, onChange, defaultValue } = this.state;

  return (
    <RadioImageFormWrapper>
      <form>
        {
          React.Children.map(this.props.children, 
            (child: React.ReactElement) =>
              React.cloneElement(child, {
                currentValue,
                onChange,
                defaultValue,
              }),
          )
        }
      </form>
    </RadioImageFormWrapper>
  )
}

Quay lại với <RadioInput />

static RadioInput = ({
  currentValue,
  onChange,
  label,
  value,
  name,
  imgSrc,
  key,
}: RadioInputProps) => (
  <label className="radio-button-group" key={key}>
    <input
      type="radio"
      name={name}
      value={value}
      aria-label={label}
      onChange={onChange}
      checked={currentValue === value}
      aria-checked={currentValue === value}
    />
    <img alt="" src={imgSrc} />
    <div className="overlay">
      {/* .... */}
    </div>
  </label>
);

Toàn bộ source code: https://codesandbox.io/s/compound-components-radio-image-form-k1h8x

  3 bước tối ưu hiệu năng React App bằng các API mới của React
  5 dự án React buộc phải có trong porfolio của bạn

Hạn chế

Với cách viết compound component này, chúng ta bị một hạn chế là bắt buộc phai viết component theo kiểu

<RadioImageForm>
	<RadioImageForm.RadioInput />
	<RadioImageForm.RadioInput />
	<RadioImageForm.RadioInput />
</RadioImageForm>

Chúng ta không được phép chèn thêm một số thẻ <div /> ở giữa nếu có nhu cầu tùy biến giao diện chẳng hạn

<RadioImageForm>
	<div>
	<RadioImageForm.RadioInput />
	<RadioImageForm.RadioInput />
	<RadioImageForm.RadioInput />
	</div>
</RadioImageForm>

Compound component Compound component với React Hook

Flexible compound component

Flexible compound component ra đời để giải quyết hạn chế của compound component, chúng ta sẽ sử dụng React Context API.

Chúng ta sẽ tạo ra một context mà ở đó cả component con và cha điều có thể truy xuất được, đúng như mục đích ra đời của Context API

const RadioImageFormContext = React.createContext({
  currentValue: '',
  defaultValue: undefined,
  onChange: () => { },
});
RadioImageFormContext.displayName = 'RadioImageForm';

Chúng ta sẽ refactor lại <RadioImageForm/>, bỏ đi đoạn React.Children.map, thay bằng <Provider />

render(): React.ReactElement {
  const { children } = this.props;

  return (
    <RadioImageFormWrapper>
      <RadioImageFormContext.Provider value={this.state}>
        {children}
      </RadioImageFormContext.Provider>
    </RadioImageFormWrapper>
  );
}

Sử dụng Provider có một lưu ý sống còn là đừng bao giờ truyền value={{ some bla bla}}, như vậy nó sẽ khác nhau trên tất cả những lần render, hãy nhớ truyền một thứ gì đó cache được và chỉ bị thay đổi khi cần thiết như this.state

Trong component con <RadioInput /> chúng ta có thể truy xuất tất cả dữ liệu nội bộ thông qua consumer, bởi vì <RadioInput /> đang nằm trong <RadioImageForm /> luôn theo cách viết của chúng ta, nên có thể khai báo một static property Consumer bên trong RadioImageForm

export class RadioImageForm extends React.Component<Props, State> {
  static Consumer = RadioImageFormContext.Consumer;
  //...

Source code ví dụ Source code Flexible compound component bằng functional component

Provider Pattern

Provider pattern là kỹ thuật kết hợp giữa React Context API và render props pattern, vẫn là để giải quyết câu chuyện chia sẻ state giữa các component trong cây.

Nếu bạn có thắc mắc, ủa vậy sao không dùng Redux, Mobx, Recoil, React Sweet State, Rematch, Unstated,… cho khỏe người ơi? Thì câu trả lời của mình là, ừ các bạn nên xài những thư viện quản lý state như vậy cho khỏe người, khỏe cho cả người maintain code bạn. Còn đây là cách làm nếu bạn muốn tham khảo, nếu không dùng gì hết, tôi dư giả thời gian để code từ đầu thì bạn có thể go-ahead với cách này

// src/components/DogDataProvider.tsx
interface State {
  data: IDog;
  status: Status;
  error: Error;
}

const initState: State = { status: Status.loading, data: null, error: null };

const DogDataProviderContext = React.createContext(undefined);
DogDataProviderContext.displayName = 'DogDataProvider';

const DogDataProvider: React.FC = ({ children }): React.ReactElement => {
  const [state, setState] = React.useState<State>(initState);

  React.useEffect(() => {
    setState(initState);

    (async (): Promise<void> => {
      try {
        // MOCK API CALL
        const asyncMockApiFn = async (): Promise<IDog> =>
          await new Promise(resolve => setTimeout(() => resolve(DATA), 1000));
        const data = await asyncMockApiFn();

        setState({
          data,
          status: Status.loaded,
          error: null
        });
      } catch (error) {
        setState({
          error,
          status: Status.error,
          data: null
        });
      }
    })();
  }, []);

  return (
    <DogDataProviderContext.Provider value={state}>
      {children}
    </DogDataProviderContext.Provider>
  );
};
// src/components/DogDataProvider.tsx

export function useDogProviderState() {
  const context = React.useContext(DogDataProviderContext);

  if (context === undefined) {
    throw new Error('useDogProviderState phải được sử dụng bên trong DogDataProvider.');
  }

  return context;
}
// src/index.tsx
function App() {
  return (
    <Router>
      <div className="App">
        {/* DataProvider phải nằm trên cùng của cây.*/}
        <DogDataProvider>
          <Nav />
          <main className="py-5 md:py-20 max-w-screen-xl mx-auto text-center text-white w-full">
            <Banner
              title={'React Component Patterns:'}
              subtitle={'Provider Pattern'}
            />
            <Switch>
              <Route exact path="/">
                {/* Component con sử dụng dữ liệu qua Consumer */}
                <Profile />
              </Route>
              <Route path="/friends">
                {/* Component con sử dụng dữ liệu qua Consumer */}
                <DogFriends />
              </Route>
            </Switch>
          </main>
        </DogDataProvider>
      </div>
    </Router>
  );
}
const Profile = () => {
  // custom hook nhận "subscribes" khi có state thay đổi
  const { data, status, error } = useDogProviderState();

  return (
    <div>
      <h1 className="//...">Profile</h1>
      <div className="mt-10">       
        {error ? (
          <Error errorMessage={error.message} />
        ) : status === Status.loading ? (
          <Loader isInherit={true} />
        ) : (
          <ProfileCard data={data} />
        )}
      </div>
    </div>
  );
};

Source Code Provider Pattern

React Component Patterns

Bài viết gốc được đăng tải tại vuilaptrinh.com

Có thể bạn quan tâm:

Xem thêm các việc làm it hấp dẫn trên TopDev

Sử dụng publisher confirm trong RabbitMQ

Sử dụng publisher confirm trong RabbitMQ

Bài viết được sự cho phép của tác giả Giang Phan

Publisher confirms là một extension của RabbitMQ để thực hiện publish Message đáng tin cậy. Khi publisher confirms được bật trên một Channel, các Message mà Producer  publish phải được xác nhận bởi Broker là đã nhận thành công/ thất bại. Từ đó chúng ta có thể ghi log, thông báo lỗi và / hoặc retry gửi tin nhắn. Trong bài viết này tôi sẽ hướng dẫn bạn sử dụng tính năng này.

  Giới thiệu CloudAMQP – Một RabbitMQ server trên Cloud
  Sử dụng publisher confirm trong RabbitMQ
Phần 12 : Kết nối RabbitMQ”]

Enabling Publisher Confirms trên một Channel

Publishers confirms không được enable theo mặc định. Để enable chúng ta gọi phương thức confirmSelect().

Channel channel = connection.createChannel(); channel.confirmSelect();

Phương thức này phải được gọi trên mọi Channel mà ta muốn sử dụng, chỉ nên được kích hoạt một lần cho một Channel, không phải cho mọi Message được publish.

Để biết một Message đã được publisher confirm hay chưa, chúng ta đăng ký một callback để được notify về kết quả publish:

Channel channel = connection.createChannel();
channel.confirmSelect();
channel.addConfirmListener((sequenceNumber, multiple) -> {
    // code when message is confirmed
}, (sequenceNumber, multiple) -> {
    // code when message is nack-ed
});

Có 2 callback:

  • Một cho Message được xác nhậ.
  • Một cho tin nhắn nack-ed (tin nhắn có thể được coi là bị mất bởi boker).

Mỗi callback có 2 tham số:

  • sequence number (số thứ tự): một số xác định Message được xác nhận hoặc nack-ed. Nó tương ứng với số Message được publish.
  • multiple: đây là một giá trị boolean. Nếu false, chỉ có một Message được xác nhận / nack-ed, nếu true, tất cả các Message có số thứ tự <= được xác nhận / nack-ed.

Chúng ta có thể lấy một sequence number của một Message trước khi nó được publish thông qua phương thức sau:

long sequenceNumber = channel.getNextPublishSeqNo());

Ví dụ Publish và Confirm từng Message

Trong ví dụ này, tôi sẽ tạo một Direct Exchange, 1 channel và enable tính năng Publisher Confirm trên Channel này.

package com.gpcoder.publisherconfirm;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class SinglePublisherConfirm {

    private static final String EXCHANGE_NAME = "PublishingMessage.DirectExchange";
    private static final String QUEUE_NAME = "PublishingMessage.DirectQueue1";
    private static final String ROUTING_KEY = "batchMessage";
    private static final int NUM_OF_MESSAGE = 6;

    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        // Create connection
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        Connection connection = factory.newConnection();

        // Create channel
        Channel channel = connection.createChannel();

        // Create direct exchange - exchange, builtinExchangeType, durable
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT, true);

        // Create queue - (queueName, durable, exclusive, autoDelete, arguments)
        channel.queueDeclare(QUEUE_NAME, true, false, false, null);

        // Bind queue to exchange - (queue, exchange, routingKey)
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, ROUTING_KEY);

        // Enabling Publisher Confirms on a Channel
        AMQP.Confirm.SelectOk confirmed = channel.confirmSelect();
        System.out.println("Enabled published confirm: " + confirmed);

        // Handling Publisher Confirms Asynchronously
        channel.addConfirmListener((sequenceNumber, multiple) -> {
            // code when message is confirmed
            System.out.println("[Confirmed - multiple] " + multiple);
            System.out.println("[Confirmed - sequenceNumber] " + sequenceNumber);
        }, (sequenceNumber, multiple) -> {
            // code when message is nack-ed
            // Message was lost, we just print the info for debug;
            // otherwise, this case should be handled differently
            System.out.println("Not-Acknowledging for message with id " + sequenceNumber);
        });

        // Publish messages to the channel and put the ids to the queue
        for (int i = 1; i <= NUM_OF_MESSAGE; i++) {             String message = "Message " + i;             System.out.println("[Send] [" + channel.getNextPublishSeqNo() + "] " + message);             channel.basicPublish(EXCHANGE_NAME, ROUTING_KEY, null, message.getBytes());             channel.waitForConfirmsOrDie(300); // in ms         }         DeliverCallback deliverCallback = (consumerTag, message) -> {
            System.out.println("[Received] : " + new String(message.getBody()));
        };

        CancelCallback cancelCallback = consumerTag -> {
            System.out.println("[Canceled]" + consumerTag);
        };

        // basicConsume - ( queue, autoAck, deliverCallback, cancelCallback)
        channel.basicConsume(QUEUE_NAME, true, deliverCallback, cancelCallback);
    }
}

Output chương trình:

Enabled published confirm: #method()
[Send] [1] Message 1
[Confirmed - multiple] false
[Confirmed - sequenceNumber] 1
[Send] [2] Message 2
[Confirmed - multiple] false
[Confirmed - sequenceNumber] 2
[Send] [3] Message 3
[Confirmed - multiple] false
[Confirmed - sequenceNumber] 3
[Send] [4] Message 4
[Confirmed - multiple] false
[Confirmed - sequenceNumber] 4
[Send] [5] Message 5
[Confirmed - multiple] false
[Confirmed - sequenceNumber] 5
[Send] [6] Message 6
[Confirmed - multiple] false
[Confirmed - sequenceNumber] 6

[Received] : Message 1
[Received] : Message 2
[Received] : Message 3
[Received] : Message 4
[Received] : Message 5
[Received] : Message 6

Như bạn thấy, các Message được xác nhận từng cái một thông qua confirm callback.

Ví dụ Publish và Confirm một Batch các Message

Tương tự như trên, nhưng chúng ta yêu cầu gửi confirm callback theo batch.

package com.gpcoder.publisherconfirm;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class BatchPublisherConfirm {

    private static final String EXCHANGE_NAME = "PublishingMessage.DirectExchange";
    private static final String QUEUE_NAME = "PublishingMessage.DirectQueue1";
    private static final String ROUTING_KEY = "batchMessage";
    private static final int NUM_OF_MESSAGE = 6;
    private static final int BATCH_SIZE = 3;

    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        // Create connection
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        Connection connection = factory.newConnection();

        // Create channel
        Channel channel = connection.createChannel();

        // Create direct exchange - exchange, builtinExchangeType, durable
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT, true);

        // Create queue - (queueName, durable, exclusive, autoDelete, arguments)
        channel.queueDeclare(QUEUE_NAME, true, false, false, null);

        // Bind queue to exchange - (queue, exchange, routingKey)
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, ROUTING_KEY);

        // Enabling Publisher Confirms on a Channel
        AMQP.Confirm.SelectOk confirmed = channel.confirmSelect();
        System.out.println("Enabled published confirm: " + confirmed);

        // Handling Publisher Confirms Asynchronously
        channel.addConfirmListener((sequenceNumber, multiple) -> {
            // code when message is confirmed
            System.out.println("[Confirmed - multiple] " + multiple);
            System.out.println("[Confirmed - sequenceNumber] " + sequenceNumber);
        }, (sequenceNumber, multiple) -> {
            // code when message is nack-ed
            // Message was lost, we just print the info for debug;
            // otherwise, this case should be handled differently
            System.out.println("Not-Acknowledging for message with id " + sequenceNumber);
        });

        // Publish messages to the channel and put the ids to the queue
        for (int i = 1; i <= NUM_OF_MESSAGE; i++) {             String message = "Message " + i;             System.out.println("[Send] [" + channel.getNextPublishSeqNo() + "] " + message);             channel.basicPublish(EXCHANGE_NAME, ROUTING_KEY, null, message.getBytes());             if (i % BATCH_SIZE == 0) {                 channel.waitForConfirmsOrDie(300); // in ms             }         }         DeliverCallback deliverCallback = (consumerTag, message) -> {
            System.out.println("[Received] : " + new String(message.getBody()));
        };

        CancelCallback cancelCallback = consumerTag -> {
            System.out.println("[Canceled]" + consumerTag);
        };

        // basicConsume - ( queue, autoAck, deliverCallback, cancelCallback)
        channel.basicConsume(QUEUE_NAME, true, deliverCallback, cancelCallback);
    }
}

Output chương trình:

Enabled published confirm: #method()
[Send] [1] Message 1
[Send] [2] Message 2
[Send] [3] Message 3
[Confirmed - multiple] true
[Confirmed - sequenceNumber] 2
[Confirmed - multiple] false
[Confirmed - sequenceNumber] 3
[Send] [4] Message 4
[Send] [5] Message 5
[Send] [6] Message 6
[Confirmed - multiple] false
[Confirmed - sequenceNumber] 4
[Confirmed - multiple] true
[Confirmed - sequenceNumber] 6

[Received] : Message 1
[Received] : Message 2
[Received] : Message 3
[Received] : Message 4
[Received] : Message 5
[Received] : Message 6

Như bạn thấy, trường hợp batch thì Message được xác nhận một lần có thể là 1 hay nhiều message.

  • [Confirmed – multiple] true và [Confirmed – sequenceNumber] 2 : nghĩa là đã xác nhận ok cho Message có số thứ tự <= 2.
  • [Confirmed – multiple] false và [Confirmed – sequenceNumber] 3 : nghĩa là đã xác nhận ok cho 1 Message có số thứ tự là 3.
  • [Confirmed – multiple] false và [Confirmed – sequenceNumber] 4 : nghĩa là đã xác nhận ok cho 1 Message có số thứ tự là 4.
  • [Confirmed – multiple] true và [Confirmed – sequenceNumber] 6 : nghĩa là đã xác nhận ok cho Message có số thứ tự <= 6.

Tài liệu tham khảo:

Bài viết gốc được đăng tải tại gpcoder.com

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Xác thực trong Spring Cloud Config (Spring Cloud Config Authenticate)

Xác thực trong Spring Cloud Config (Spring Cloud Config Authenticate)

Bài viết được sự cho phép của tác giả Trần Hữu Cương

Thông tin cấu hình của 1 project khá quan trọng, nó chứa nhiều thông tin nhạy cảm như username/password… nên ta cần phải bảo mật nó.
Để bảo mật thông tin cấu hình từ cloud config server có 2 cách đơn giản:

  • Xác thực (dùng username/password hoặc token)
  • Mã hóa/ giải mã (mã hóa ở cloud config server, và giải mã ở cloud config client)

Trong bài này mình sẽ thực hiện theo cách thứ nhất là xác thực các request tới cloud config server.

  Bí kíp tạo website nhờ vào GitHub và Cloudflare
  Cloud Devops quan trọng như thế nào?

Xác thực trong Spring Cloud Config (Spring Cloud Config Authenticate)

Trong bài này mình sẽ sử dụng lại ví dụ trong bài trước:

Đối với project Spring Cloud Config Server

Thêm thư viện spring security vào file pom.xml:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

Cấu hình security (username/password) trong file application.yml

security:
 user:
 name: admin1234
 password: admin1234

Đối với project Spring Cloud Config Client

Cấu hình username/password cho cloud config: trong file bootstrap.yml

cloud:
 config:
 uri: http://localhost:8888
 username: admin1234
 password: admin1234

Demo: start project spring-cloud-config-server

Truy cập http://localhost:8888/app/dev để xem thông tin cấu hình của ứng dụng app với profiles là dev

Xác thực trong Spring Cloud Config (Spring Cloud Config Authenticate)

Server bắt buộc phải login mới có thể xem được.

Trong trường hợp này bạn phải nhập username/password đã cấu hình ở bên trên để pass qua màn hình login.

Cách khác là bạn có thể truyền luôn username/password vào trong url: http://admin1234:admin1234@localhost:8888/app/dev. Tuy nhiên trình duyệt web ko hỗ trợ kiểu url này nên bạn có thể thử bằng 1 rest client như postman hoặc mở màn hình cmd và chạy lệnh curl:

curl http://admin1234:admin1234@localhost:8888/app/dev

Xác thực trong Spring Cloud Config (Spring Cloud Config Authenticate)

Còn đối với spring-cloud-config-client, do đã cấu hình sẵn username/password nên nó vẫn có thể lấy được cấu hình từ server như bình thường.

Xác thực trong Spring Cloud Config (Spring Cloud Config Authenticate)

Okay, Done!

Download code ví dụ trên tại đây hoặc tại: https://github.com/stackjava/spring-cloud-config-authenticate

References: https://cloud.spring.io/spring-cloud-config/reference/html/

Bài viết gốc được đăng tải tại stackjava.com

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Những loại virus nguy hiểm nhất mọi thời đại (Phần 1)

Những loại virus nguy hiểm nhất mọi thời đại (Phần 1)

Bài viết được sự cho phép của tác giả Trần Thị Thu Hà

Kể từ ngày virus đầu tiên xuất hiện, đến nay đã hơn 20 năm. Cũng có nhiều virus mới ra đời, dưới đây là một số loại virus nguy hiểm nhất, gây thiệt hại nặng nhất.

  Sử dụng biến Node Environment
  Nhân sự nên làm gì giữa tâm bão Coronavirus

1. CIH (1998)

Ước tính thiệt hại 20-28 triệu USD trên toàn thế giới, không tính dữ liệu PC bị phá hủy. CIH có nguồn gốc từ Đài Loan (6/1998) được nhận dạng là một trong những virus nguy hiểm và có sức tàn phá lớn nhất. CIH còn được biết đến với tên là Chernobyl vì thời điểm kích hoạt trùng với ngày xảy ra vụ nổ nhà máy nguyên tử Chernobyl. Virus này tấn công vào các file thực thi của hệ điều hành Windows 95,98 và ME, có khả năng cư trú trên bộ nhớ máy tính để lây nhiễm và các file thực thi khác.

Những loại virus nguy hiểm nhất mọi thời đại (Phần 1)

Chỉ sau một thời gian ngắn hoạt động CIH có thể ghi đè dữ liệu trên ổ cứng, biến dữ liệu trở nên vô dụng. Tuy nhiên ngày này CIH không còn nguy hiểm bởi các hệ điều hành mới như Windows XP, 2000 đã được cải tiến.

2. Melissa (1999)

Những loại virus nguy hiểm nhất mọi thời đại (Phần 1)

Ngày 26/3/1999, virus Melissa đã lây nhiễm toàn cầu, ước tính thiệt hại 300-600 triệu USD. Virus dạng kịch bản macro trong Word này đã lây nhiễm vào 15/20 chiếc máy tính doanh nghiệp trên toàn cầu. Melissa phát tán nhanh đến nỗi Intel, Microsoft và một số hãng phần mềm khác sử dụng Outlook đã buộc phải đóng toàn bộ hệ thống e-mail để hạn chế thiệt hại.

Melissa sử dụng Outlook để gửi mail đính kèm bản virus tới 50 email trong danh sách liên lạc. Email này có câu: “”Here is that document you asked for…don’t show anyone else. ;-)””. Khi nhấn vào file đính kèm virus sẽ lây vào máy tính và lặp lại chu trình phát tán.

3. ILOVEYOU (2000)

ILOVEYOU còn được biết với cái tên Loveletter và The Love Bug, một dạng Visual Basic với cái tên ngọt ngào: Lời hứa tình yêu. ILOVEYOU lần đầu tiên được phát hiện vào ngày 3/5/2000 tại Hồng Kông sau đó lây lan nhanh qua email với dòng tiêu đề ILOVEYOU cùng file đính kèm: Love-Letter-For-You.txt.vbs.

Những loại virus nguy hiểm nhất mọi thời đại (Phần 1)

Cách phát tán của ILOVEYOU cũng tương tự như Melissa. Nguy hiểm hơn nữa là virus này còn tìm tên và mật khẩu người dùng và gửi tới email tác giả. Thiệt hại ước tính là 10-15 triệu USD. Tác giả của ILOVEYOU không bị kết án do thời điểm đó Philippines không có luạt chống tội phạm máy tính.

4. Code red (2001)

Còn có tên là Bady được thiết kế với mục đích phá hủy mức lớn nhất có thể. Đây là một dạng sâu máy tính lây nhiễm trên hệ thống máy chủ, xuất hiện ngày 13/7/2001 với thiệt hại ước tính 2,6 triệu USD.

Những loại virus nguy hiểm nhất mọi thời đại (Phần 1)

Loại virus này vô cùng độc hại bởi đích đến của chúng là các máy tính chạy phần mềm máy chủ web internet information server (IIS). Code red có khả năng khai thác một lỗ hồng trong IIS. Khi đã lây nhiễm, website lưu trữ trên máy chủ sẽ hiển thị: “Hello! Welcome to http://www.worm.com! Hack by Chinese!”.

Sau đó nó sẽ tìm kiếm các máy chủ bị lỗi và lây nhiễm. Chưa đến một tuần, Code red đã lây nhiễm khoảng 400 nghìn máy chủ trên toàn thế giới.

5. SQL Slammer (2003)

Những loại virus nguy hiểm nhất mọi thời đại (Phần 1)

SQL Slammer được kích hoạt vào thứ 7 (thường là ngày nghỉ của dân văn phòng) nên thiệt hại về tiền không cao. Tuy nhiên virus này cũng đã lây nhiễm 500 nghìn máy chủ trên toàn thế giới và cũng là nhân tố tạo nên cơn bão dữ liệu ồ ạt, khiến toàn bộ hệ thống Internet của Hàn Quốc bị sập trong 12 giờ đồng hồ. SQL Slammer còn được gọi là Sapphire,kích hoạt vào ngay 25/2/2003 có tác động rất xấu đến toàn bộ giao vận Internet toàn cầu.

Virus này chỉ tìm kiếm các máy chủ, SQL Slammer là một gói dữ liệu đơn lẻ và tự gửi tới các địa chỉ IP. Nếu địa chỉ IP là một máy tính chạy bẳn SQL Server Desktop Engine chưa được vá lỗi thì chiếc máy chủ đó sẽ bị nhiếm virus ngày lập tức và tấn công các địa chỉ IP khác.

Với phương thức lây nhiễm này, Slammer có thể tấn công 75 nghìn máy tính chỉ trong 10 phút, khiến toàn bộ mạng internet bị tắc nghẽn, các router phải ngưng hoạt động.

Các bạn nhớ đón đọc phần 2 nhé.

Bài viết gốc được đăng tải tại smartjob.vn

Có thể bạn quan tâm:

Xem thêm Jobs IT for Developer hấp dẫn trên TopDev

Lập trình Android trên thiết bị thật qua USB cable

Lập trình Android trên thiết bị thật qua USB cable

Bài viết được sự cho phép của tác giả Trần Hữu Cương

Thông thường, khi lập trình android, sau khi viết code xong, bạn sẽ chạy thử ứng dụng bằng máy áo cài đặt sẵn trên IDE hoặc các máy ảo như Genymotion. Tuy nhiên chạy ứng dụng qua máy ảo khá chậm nhất là với những máy tính có cấu hình yếu

Trong bài này, mình sẽ thực hiện chạy thử các chương trình trực tiếp trên thiết bị thật.

Tuyển android không cần kinh nghiệm

  10 tài liệu lập trình Android miễn phí từ cơ bản đến nâng cao
  5 ứng dụng Android tuyệt vời dành cho Android Developer và Designer

Lập trình Android trên thiết bị thật qua USB cable

Đầu tiên bạn phải bật chế độ Developer options trên điện thoại

Mở điện thoại và chuyển đến mục Setting(Cài đặt). Sau đó, hãy chuyển đến “About phone” ( Giới thiệu về điện thoại)
Nếu Developer Options (Tùy chọn nhà phát triển) không được hiển thị trong thiết bị của bạn. Bạn cần nhấp 7 lần vào Build number để hiện Developer Options
Sau đó ra ngoài, vậy là ta đã có Developer options. Tiếp theo, bạn vào bật chế độ USB Debugging lên:

Lập trình Android trên thiết bị thật qua USB cable

Nếu có được hỏi xác thực ủy quyền cho máy tính thì chọn Always allow this computer và nhấn OK.

Và giờ chúng ta chỉ cần nhấn run project rồi sẽ hiện bảng thông báo bạn muốn chọn thiết bị nào.

Lập trình Android trên thiết bị thật qua USB cable

Nếu có tên thiết bị như trên là bạn đã cài đặt thành công máy thật connect với máy tính.

Vậy chúng ta đã cài đặt máy ảo và thiết bị thật để lập trình Android.

Bài viết gốc được đăng tải tại codecute.com

Có thể bạn quan tâm:

Xem thêm tuyển dụng ngành it hấp dẫn trên TopDev

50 keywords mà mọi lập trình viên java nên biết

50 keywords mà mọi lập trình viên java nên biết

Bài viết được sự cho phép của tác giả Trần Thị Thu Hà

Java hiện là ngôn ngữ lập trình phổ biến hàng đầu tại Việt Nam và rất nhiều sinh viên CNTT muốn theo đuổi ngôn ngữ này để phát triển sự nghiệp của mình. Có không ít khó khăn bạn cần phải vượt qua để làm chủ ngôn ngữ đầy rắc rối ấy và việc đầu tiên là hiểu những keywords – những từ khóa trong lập trình java. Việc này sẽ làm tiền đề giúp bạn trong việc tự học, tự trải nghiệm thách thức từ java.

  10 Java Web Framework tốt nhất
  10 lý do cho thấy tại sao bạn nên theo học ngôn ngữ lập trình Java

Hiện nay, Java có khoảng 50 keywords và Topdev sẽ giúp bạn liệt kê hết những từ khóa này ngay sau đây:

Keyword:

Abstract: Khai báo lớp, phương thức và interface trừu tượng không có thể hiện (instance) cụ thể

Assert: Kiểm tra điều kiện đúng hay sai (hay dùng trong Unit Test)

Bloolean: Khai báo biến kiểu logic với hai giá trị: True or False

Break: Lệnh switch-case hoặc dùng để thoát khỏi vòng lặp

Byte: Các giá trị nguyên chiếm 8 bit (1byte)

Case: Trường hợp được chọn theo Switch (chỉ dùng khi được đi kèm Switch)

Catch: Dùng để bắt ngoại lệ, dùng kèm với try để xử lý những ngoại lệ nảy sinh trong chương trình

Char: Là kiểu ký tự Unicode, mỗi ký tự có 16 bit (2 byte)

Class: Dùng để định nghĩa class

Const: Không thể dùng trong java bởi nó chưa được sử dụng

Continue: Được dùng để dừng chu trình (interation) lặp hiện tại và bắt đầu chu trình kế tiếp

50 keywords mà mọi lập trình viên java nên biết

Default: Mặc định được thực thi nếu không có case nào trả về giá trị True – được dùng trong Switch case.

Do: Dùng ở  vòng lặp While

Double: Là kiểu số thực có các giá trị được biểu diển bởi dấu phẩy động 64 bit (8byte)

Else: Rẽ nhánh điều kiện ngược với If

Enum: Kiểu dữ liệu Enum – tương đối giống với kiểu dữ liệu mảng. Khác biệt ở chỗ các phần tử của kiểu này có thể bổ sung thêm các phương thức.

Extends: Dùng để định nghĩa lớp con kế thừa những thuộc tính và phương thức từ lớp cha.

Final: Dùng để chỉ ra các biến – phương thức không thay đổi sau khi đã được định nghĩa. Những phương thức final không được kế thừa và override.

Finally: Thực hiện một khối lệnh đến cùng, bỏ qua các ngoại lệ – dùng trong Try-cactch.

Float: Kiểu số thực – Các giá trị được biểu diện bởi dạng dấu phẩy động 32 bit.

For: Dùng trong vòng lặp for – Các bước lặp đã xác định từ trước.

Goto: Chưa được sử dụng

If: Là lệnh chọn theo điều kiện logic

Implements: Xây dựng 1 lớp mới cài đặt những phương thức từ interface xác định trước

Import: Dùng để yêu cầu 1 hay 1 vài lớp ở các gói chỉ định cần nhập vào để sử dụng trong ứng dụng hiện thời

Long: Là kiểu số nguyên lớn – Các giá trị chiếm 64 bit (8 byte)

Native: Sử dụng khi lập trình viên muốn dùng code bằng ngôn ngữ khác

New: Khởi tạo đối tượng

Package: Sử dụng khi xác định 1 gói sẽ chứa một số lớp trong file mã nguồn

Private: Khai báo biến dữ liệu, phương thức riêng trong từng lớp và chỉ cho phép truy cập trong lớp đó.

Protected: Dùng để khai báo biến dữ liệu – Chỉ được truy cập ở lớp cha và những lớp con của lớp đó.

Public: Dùng để khai báo biến dữ liệu, lớp – Phương thức công khai có thể tự truy cập ở mọi hệ thống.

Return: Kết thúc phương thức, trả về giá trị cho phương thức.

Short: Kiểu số nguyên ngẵn – giá trị chiếm 16 bit (2byte)

Static: Định nghĩa biến, phương thức của một lớp có thể được truy cập trực tiếp từ lớp mà không thông qua khởi tạo đối tượng của lớp.

Super: Biến chỉ tới đối tượng ở lớp cha

Switch: Sử dụng trong câu lệnh điều khiển Switch case

Synchronized: Chỉ ra là ở mõi thời điểm chỉ có 1 đối tượng hay 1 lớp có thể truy nhập đến biến dữ liệu hoặc phương thức loại đó – Thường được sử dụng trong lập trình đa luồng (multithreading).

This: Biến chỉ tới đối tượng hiện thời

Throw: Tạo một đối tượng Exception nhằm chỉ định 1 trường hợp ngoại lệ xảy ra

Throw: Chỉ định cho qua ngoại lệ nếu exception xảy ra

Transient: Chỉ định rằng nếu một đối tượng được Serialized, giá trị của biến sẽ không cần được lưu trữ

Try: Thử thực hiện cho đến khi xảy ra 1 ngoại lệ

Void: chỉ định 1 phương thức không trả về giá trị

Volatile: Báo cho chương trình dịch biết là biến khai báo volatile có thể thay đổi tùy ý trong các luồng (thread)

While: Sử dụng trong lệnh điều khiển While

Bài viết gốc được đăng tải tại smartjob.vn

Có thể bạn quan tâm:

Xem thêm Việc làm Java lương cao hấp dẫn trên TopDev