Home Blog Page 82

Lập trình web cơ bản với Javascript jQuery

javascript jquey
Lập trình web cơ bản với Javascript jQuery

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

Lập trình web cơ bản với Javascript jQuery

Giáo trình Javascript jQuery bản tổng hợp từ cơ bản đến nâng cao bằng tiếng Việt

Giáo trình cung cấp những kiến thức cơ bản nhất cho những ai chưa biết về Javascript và hướng dẫn sử dụng thư viện jQuery của Javascript. Các kiến thức thực tế cần thiết cho việc xây dựng một trang web sẽ được liệt kê và phân tích đầy đủ, rõ ràng.

  10 câu hỏi javascript để nâng cao trình độ
  10 tip tối ưu code trên JavaScript mà web developer nào cũng nên biết

Xem thêm nhiều việc làm JavaScript hấp dẫn trên TopDev

Review về Ebook

Javascript là một ngôn ngữ lập trình kịch bản hướng đối tượng, được phát triển bởi Nestcape và có sự hậu thuẫn mạnh mẽ từ Apple, Microsoft, Oracle, Sybase,… Với sự gia đời của Javascript, các trang web tĩnh HTML trở nên thân thiện và hữu dụng hơn lúc nào hết. Ebook về Javascript bao gồm các chương cơ bản sau:

  • Chương 1: Lời nói đầu
  • Chương 2: Nhập môn Javascript (nhúng Javascript vào file HTML, giới thiệu các thẻ, cách hiển thị một dòng text,…)
  • Chương 3: Các biến trong Javascript, các câu lệnh, mảng,…
  • Phần câu hỏi và bài tập

Với sự phát triển rất mau lẹ của Internet, người dùng ngày càng quan tâm tới hình thức của một trang web. Trước đây, website của bạn chỉ cần banner, nội dung và chút footer là đã hoàn chính. Nhưng giờ đây, tất cả các yếu tố đó cần được đầu tư kỹ lưỡng hơn, lạ mắt hơn để thu hút người dùng. Bởi vậy, các designer bắt đầu hướng sự chú ý đến các thư viện Javascript mở như jQuery nhằm tạo ra những hiệu ứng tương tác trực tiếp tới người đọc.

Các bạn có thể tải Ebook về Javascript tại đây.

Đó là những tài liệu cung cấp kiến thức lập trình web cơ bản nhất cho người mới bắt đầu. Ngoài ra, bạn có thể tham khao thêm những bài viết về lập trình được đội ngũ kỹ thuật viết tại Cẩm nang lập trì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 Việc làm IT hấp dẫn trên TopDev

Hướng dẫn sử dụng composer cơ bản

composer
Hướng dẫn sử dụng composer cơ bản

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

Composer quản lý sự phụ thuộc của một dự án với các thư viện lập trình bên ngoài thông qua một số các tập tin và liên quan đến một số thuật ngữ, chúng ta sẽ bắt đầu tìm hiểu cách sử dụng composer nhé.

Composer.json file chứa các thiết lập dự án

Để bắt đầu một dự án bạn cần có một file composer.json, file này chứa mô tả các thư viện ngoài mà dự án cần cài đặt (phụ thuộc) bằng từ khóa require.

{
    "require": {
        "monolog/monolog": "1.0.*"
    }
}

Phần thiết lập trên nói lên rằng dự án cần gói có tên là monolog/monolog với yêu cầu phiên bản là 1.0.*. Composer sẽ sử dụng thông tin này và tìm kiếm các gói được đăng ký bằng từ khóa repositories hoặc trong Packagist là một kho tài nguyên các gói thư viện trên mạng. Chúng ta tiếp tục làm quen một số thuật ngữ:

Package name

Package name chứa tên nhà cung cấp và tên dự án, ví dụ trên tên nhà cung cấp và tên dự án trùng nhau là monolog. Có thể hai nhà cung cấp khác nhau đặt trùng tên dự án, ví dụ igorw/json là dự án json của nhà cung cấp igorw khác với gói thư viện seldaek/json là dự án json của nhà cung cấp seldaek.

Hạn chế phiên bản gói thư viện

Chúng ta có thể hạn chế phiên bản gói cần cài đặt để đảm bảo dự án hoạt động tốt với tính năng của gói ở một số phiên bản. Trong ví dụ trên, chúng ta yêu cầu gói monolog/monolog với hạn chế phiên bản là 1.0.* tức là các phiên bản >1.0 và <1.1 thỏa mãn yêu cầu.

  Hướng dẫn sử dụng composer cơ bản

Sử dụng composer cài đặt các gói cần thiết

Thực hiện cài đặt các gói đã được khai báo trong composer.json bằng lệnh

php composer.phar install

Nếu bạn đã thêm đường dẫn đến composer.bat vào biến môi trường PATH thì chỉ cần gõ ngắn gọn hơn:

composer install

Khi chạy lệnh cài đặt này sẽ có hai tình huống xảy ra:

  • Nếu trước đó bạn chưa chạy lệnh này bao giờ sẽ không có file composer.lock. Composer sẽ đơn giản là đọc thông tin các gói cần thiết trong composer.json và tải phiên bản mới nhất trong hạn chế phiên bản về thư mục vendor trong dự án. Trong ví dụ trên khi thực hiện lệnh composer install xong chúng ta sẽ thấy có thư mục monolog/monolog trong thư mục vendor của dự án. Khi composer cài đặt xong, tất cả các gói cùng với phiên bản chính xác sẽ được lưu vào composer.lock, bởi vậy tất cả mọi người tham gia dự án sẽ bị lock ở cùng một phiên bản các gói thư viện lập trình.
  • Nếu file composer.lock tồn tại, có nghĩa là bạn đã chạy lệnh install trước đó hoặc có thể một ai đó đã chạy lệnh install và commit file composer.json. Chạy lệnh install khi có tập tin composer.lock giúp Composer sử dụng phiên bản chính xác được liệt kê trong composer.lock và đảm bảo phiên bản các gói thư viện sẽ phù hợp với mọi người đang tham gia trong dự án. Kết quả bạn sẽ có các phiên bản được yêu cầu trong composer.json nhưng không phải tất cả chúng ở phiên bản mới nhất do một số liệt kê trong composer.lock đã phát hành phiên bản mới hơn. Thiết kế này đảm bảo dự án của bạn không bị phá vỡ do những thay đổi bất ngờ trong các gói thư viện.

Commit composer.lock với trình quản lý phiên bản

Như đã viết ở trên, composer.lock sẽ ngăn chặn việc tự động lấy xuống các phiên bản mới nhất, để cập nhật chúng sử dụng lệnh update. Khi chạy lệnh này nó sẽ lấy tất cả các phiên bản mới nhất phù hợp với hạn chế phiên bản trong composer.json và sau đó nó update các thông tin phiên bản chính xác vào composer.lock.

php composer.phar update

hay ngắn gọn

composer update

Chú ý: Composer sẽ hiển thị một cảnh báo khi sử dụng lệnh install mà file composer.json và composer.lock chưa được đồng bộ. Nếu bạn chỉ muốn cập nhật một gói thư viện cụ thể, có thể sử dụng lệnh:

php composer.phar update monolog/monolog [...]

Packagist

Packagist là một nơi chứa các gói thư viện chính của Composer, bạn có thể truy cập Packagist tại https://packagist.org. Bạn có thể tải về các gói thư viện tại đây, vì vậy bạn có thể sử dụng lệnh require để yêu cầu bất kỳ gói thư viện nào có trên Packagist.

php composer.phar require vendor/package:2.*

Gói vendor/package phiên bản hạn chế 2.* sẽ được kiểm tra trong file composer.json, nếu chưa có sẽ được thêm vào phần require. Sau khi thêm hoặc thay đổi composer.json, các gói yêu cầu sẽ được cài đặt hoặc cập nhật.

Composer gọi các gói thư viện trong lập trình như thế nào?

Composer tạo ra file vendor/autoload.php, file này dùng để include vào bắt đầu sử dụng các class mà gói thư viện cung cấp.

require __DIR__ . '/vendor/autoload.php';

$log = new Monolog\Logger('name');
$log->pushHandler(new Monolog\Handler\StreamHandler('app.log', Monolog\Logger::WARNING));
$log->addWarning('Foo');

Bạn có thể thêm các đoạn code riêng vào autoloader này bằng cách thêm vào trường autoload trong composer.json:

{
    "autoload": {
        "psr-4": {"Acme\\": "src/"}
    }
}

Composer sẽ đăng ký PSR-4 cho namespace Acme. src là một thư mục nằm trong thư mục gốc của dự án, ngang mức với thư mục vendor, một file src/Foo.php chứa class Acme/Foo. Sau khi thêm autoload, bạn phải chạy lệnh dump-autoload để hệ thống build lại file vendor/autoload.php. Sau đó, bạn cũng include file vendor/autoload.php và gọi được các class mà bạn tự viết.

$loader = require __DIR__ . '/vendor/autoload.php';
$loader->addPsr4('Acme\\Test\\', __DIR__);

Thuật ngữ PSR-4 là viết tắt của PHP Standards Recommendation 4 là chuẩn quy ước viết code do nhóm FIG(Framework Interop Group) đề xuất và hiện tại có 5 chuẩn là PSR-0 đến PSR-4. Chúng tôi sẽ trở lại bài viết chi tiết các chuẩn này trong bài Các tiêu chuẩn viết code trong PHP.

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

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

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

Bazel 4.1.0: Bài 2 – khái niệm và thuật ngữ

khái niệm bazel
Bazel 4.1.0: Bài 2 – khái niệm và thuật ngữ

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

Workspace, packages và targets

Workspace

Workspace là file để giúp bazel hiểu các thành phần source code để build ứng dụng của bạn. Nó là text file và có tên là WORKSPACE, nó có thể rỗng hoặc chứa các phụ thuộc bên ngoài để build ứng dụng.

  Bazel 4.1.0: Bài 1 – Cài đặt bazel 4.1.0
  "Làm PM, theo anh không cần biết về code, nhưng phải hiểu về SQL, database, những khái niệm cơ bản của code"

WORKSPACE.bazel hay WORKSPACE trong bazel đều là 1.

ví dụ về WORKSPACE của telegram. File này nằm ở thư mục root của source code.

Repositories

Cách tổ chức source code gọi là repositories. Thư mục có chứa file WORKSPACE gọi là thư mục chính, đặt tên là @. Các repositories bên ngoài định nghĩa trong WORKSPACE theo workspace rules. Các quy tắc xem ở đây.

Các repositories bên ngoài cũng có WORKSPACE. Tuy nhiên Bazel sẽ bỏ qua chúng.

Packages

Đơn vị tổ chức source code bằng repository gọi là package. Một package là cách tổ chức các files liên quan tới nhau và phụ thuộc giữa chúng.

Một package được định nghĩa trong 1 thư mục và chứa file BUILD hay BUILD.bazel, nằm bên trong thư mục root chứa file WORKSPACE. Chúng ta hiểu nôm na là các submodule cũng được.

Các package của Telegram-iOS

Ví dụ về cách tổ chức 1 package của Telegram-iOS:

Targets

Một package thì gọi là 1 nơi chứa source code. Còn các thành phần của 1 package thì gọi là target. Các target được quy định qua file và quy tắc của nó. Group target được định nghĩa ở đây.

Các package group được định nghĩa bởi package_group.

Labels

Tên của 1 target gọi là label. Tên điển hình có dạng như sau:

@myrepo//my/app/main:app_binary

Label @myrepo  thường được viết như sau:

//my/app/main:app_binary

Package names, //package-name:...

Tên của package được định nghĩa ở BUILD file của nó.

Rules

Rules là quy tắc giữa input và output, và các bước để build ra outputs. Mọi rule đều có 1 tên định nghĩa qua attribute name. Ví dụ:

swift_library(
    name = "AccountContext",
    module_name = "AccountContext",
    srcs = glob([
        "Sources/**/*.swift",
    ]),

BUILD files

Là tập hợp các quy tắc mà chúng ta đã mô tả qua packages, targets và labels ở trên. Mỗi package chứa 1 BUILD file là 1 chương trình nhỏ.

Loading an extension

Bazel sử dụng các file kết thúc bằng .bzl để load các extension:

load("//foo/bar:file.bzl", "some_library")

Nó sẽ load thư viện some_library bên ngoài và đưa vào chương trình.

Kiểu của build rule

Tùy ngôn ngữ mà sẽ có từng type khác nhau, ví dụ cc_binary, cc_library và cc_test là rule của C++.

Dependencies

Một target A phụ thuộc 1 target B thì cần 1 quy tắc để mô tả nó, gọi là dependency graph. Nếu B sử dụng code trong C nữa thì khi đó A sẽ có ràng buộc trong BUILD file như sau:

rule(
    name = "a",
    srcs = "a.in",
    deps = "//b:b",
)

B có build file như sau:

rule(
    name = "b",
    srcs = "b.in",
    deps = "//c:c",
)
a_b_c.svgbiểu đồ phụ thuộc nhau
Danh mục
Có thể bạn quan tâm:

Selenium IDE – Record and Playback

selenium IDE
Selenium IDE – Record and Playback

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

Để đáp lại lòng mong mỏi & yêu cầu của rất rất nhiều bạn đọc gần xa sau bài “Giới thiệu công cụ kiểm thử tự động Selenium“, chào mừng các bạn trở lại với Selenium phần 2 của mình – Selenium IDE – Record and Playback. Hi vọng không có quá nhiều bạn bị găm miểng sau câu đầu “cưa bom” của mình.

Như hầu hết tất cả các test tool, Selenium cũng hỗ trợ chức năng Record/Playback để chúng ta có thể tạo ra những test script đơn giản, không cần quá nhiều xử lý code hay exception. Selenium IDE đơn giản sẽ copy và làm chính xác hầu hết hành động của chúng ta trên một ứng dụng web.

  Download, Export file tự động với Selenium Webdriver
  Giới thiệu công cụ kiểm thử tự động Selenium

Trước hết, Selenium IDE là một add-on của FireFox. Chúng ta chỉ có thể cài đặt và Record trên FireFox mà thôi. Ở version 1.X, Selenium IDE chỉ cho phép chúng ta Playback trên FireFox, nhưng ở version 2.X, chúng ta có thể Playback trên hầu hết browser hiện hành như IE hay Chrome.

Bước đầu tiên là cài đặt add-on Selenium IDE trên FireFox. Thật đơn giản, chúng ta chỉ cần vào phần add-on của FireFox, search Selenium và cài đặt như một add-on bình thường. Bạn cũng có thể vào trang chủ của Selenium và download nó.

download selenium IDE

Sau khi chọn download, FireFox sẽ hỏi lại để chắc chắn là chúng ta muốn cài đặt add-on này lên browser. Các bạn chọn “Allow” và “Install Now”

Selenium IDE AllowSelenium IDE Install

Sau khi cài đặt Selenium IDE (các bạn có thể xem đoạn clip này để rõ hơn), chúng ta sẽ thể thấy menu item của Selenium trong menu Tools.

Installed Selenium IDE

Hotkey của Selenium IDE là Ctrl+Alt+S. Màn hình chính của Selenium IDE như sau:

Selenium IDE Editor

  • Base URL là nơi lưu trữ homepage của ứng dụng web
  • Test Case list liệt kê tất cả test case có trong test suite
  • Fast…Slow xác định tốc độ execute một test case
  • Play entity test suite thực thi tất cả test case chúng ta đang mở
  • Play current test case thực thi test case đang được mở
  • Pause/Resume: Tạm ngưng/Tiếp tục thực thi test case đang chạy
  • Step: thực thi từng bước một trong test case. Chỉ có tác dụng khi test case đang tạm ngưng
  • Apply Rollup Rules: Chức năng đặc biệt cho phép chúng ta nhóm nhiều action nhỏ thành một action lớn
  • Record Sao chép lại hành động của chúng ta và ghi ra danh sách action.
  • Table/Source danh sách các action trong test case
  • Command danh sách các action mà Selenium IDE đang hỗ trợ
  • Target định nghĩa control mà chúng ta đang tương tác. Các bạn có thể xem chi tiết ở bài Selenium – Xác Định Đối Tượng UI
  • Value dữ liệu test
  • Log thông tin về action đang được thực thi
  • Reference hướng dẫn sử dụng action đang được chọn
  • UI-Element and Rollup được sử dụng ở mức advance, khi mà chúng ta tự thiết kế các nhận diện control hay gom nhóm action.

Next, chúng ta thử Record bằng cách tương tác trên Firefox

Như các bạn thấy, chúng ta làm đến đâu là Selenium IDE sẽ copy và tạo ra một dòng action tương ứng…

Selenium IDE Record

và, Playback…..

Congratulation, các bạn đã tạo ra một test case bằng Selenium IDE (Youtube)

Cuối cùng, chúng ta lưu test case lại để có thể tái sử dụng vào lần sau (Regression Test). Ở đây, Selenium IDE có hai chức năng, Save và Export. Chức năng Save sẽ lưu test case của chúng ta ở dạng html, giống như những gì chúng ta thấy trong tab Source. Chức năng Export dùng để phát sinh ra code ở nhiều ngôn ngữ khác nhau như Python, Java, C#, Ruby. Các bạn chú ý là Export sẽ ra hai dạng code khác nhau, RC và WebDriver. Đây là hai dạng của Selenium Scripting mà mình đã đề cập ở phần một. Khi Save test case ở dạng html, chúng ta có thể mở lại test case trong Selenium IDE và Playback. Khi Export test case ra code, chúng ta không thể import lại Selenium IDE để Playback, mà chúng ta chỉ có thể sử dụng nó trong một framework khác như VS, Eclipse hay RobotFramework.

Selenium IDE Save

Hẹn các bạn ở phần 3 “Selenium IDE – Record and Playback trên các trình duyệt (không phải Firefox)


Các clips minh họa:

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 IT hấp dẫn trên TopDev

Hướng dẫn tắt cách tắt Superfetch (SysMain) trên Windows 10

tắt superfetch
Hướng dẫn tắt cách tắt Superfetch (SysMain) trên Windows 10

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

Tuy đã được ra mắt từ rất lâu và thua kém rất nhiều mặt khi so sánh ổ cứng HDD với ổ SSD, nhưng không thể phủ nhận một điều là hiện nay ổ cứng HDD vẫn đang được sử dụng rất rộng rãi trong việc lưu trữ dữ liệu.

Bởi khi chọn ổ cứng để lưu trữ dữ liệu thì tốc độ đọc ghi không còn là yếu tố quan trọng với người dùng cá nhân nữa, mà thay vào đó dung lượng lớn mới là yếu tố được đặt lên hàng đầu.

Lớn nhất hiện tại là ổ cứng có dung lượng 20TB của Seagate và đang có xu hướng tăng dần, cùng với mức giá mềm hơn rất rất nhiều khi so với ổ cứng SSD cùng dung lượng.

  Tìm hiểu về tiến trình Superfetch (Sysmain) trên Windows
  Fix Lỗi "RDP Authentication Error Has Occurred – The Function Requested Is Not Supported"

Ngoài ra, ổ HDD cũng đang là thiết bị lưu trữ dữ liệu chính của máy tính, đặc biệt là trên các mẫu PC/ Laptop giá rẻ cho học sinh, sinh viên hoặc các máy tính đời cũ.

Mà khi sử dụng hệ điều hành Windows 10 với ổ cứng HDD thì đồng nghĩa với việc bạn sẽ phải đối mặt với lỗi Full Disk 100%, máy thường xuyên xảy ra hiện tượng giật lag khi làm việc với các tác vụ nặng.

cach-tat-superfetch-sysmain-tren-windows-10 (1)

May mắn là chúng ta vẫn có thể áp dụng một vài thủ thuật để tinh chỉnh/ thiết lập để có thể giảm bớt được tình trạng này.

Và ở trong vài viết này mình sẽ hướng dẫn cho các bạn cách tắt service Superfetch (Sysmain) trên Windows để khắc phục lỗi Full Disk trên Windows 10 nhé !

I. Cách tắt Superfetch (Sysmain) trên Windows 10

Trên blog đã có vài bài hướng dẫn cách tối ưu và tăng tốc Windows 10, trong đó cũng nói về cách tắt dịch vụ Superfetch (ở phần #6), cùng hướng dẫn tắt sử dụng Services Manager mặc định của Windows 10.

Thế nên bạn hãy đọc lại các bài viết đó nếu muốn nhé, còn trong khuôn khổ của bài viết này mình sẽ không nói lại nữa.

Mà ở đây mình sẽ chia sẻ cho các bạn vài cách nâng cao để có thể tắt dịch vụ Sysmain trên Windows trong trường hợp không thể dùng được Services Manager.

Nhưng trước tiên, nếu bạn chưa biết gì về Superfetch (sysmain) thì có thể tham khảo bài viết này nhé: Tìm hiểu về tiến trình Superfetch (Sysmain) trên Windows

I. Cách tắt Sysmain bằng các tinh chỉnh trong Registry của Windows

Registry là nơi lưu trữ các thông tin cũng như hầu hết các thiết lập của hệ điều hành Windows, với nó bạn có thể can thiệp rất sâu vào hệ thống bằng các tinh chỉnh đơn giản.

Trái lại, chỉnh sửa Registry đi kèm với rủi ro lỗi Windows rất cao nên bạn cần backup lại toàn bộ Registry trước khi thực hiện theo bất cứ hướng dẫn nào, để có thể khôi phục khi cần – tránh mất dữ liệu không đáng có.

Thực hiện:

+ Bước 1: Đầu tiên, bạn mở hộp thoại RUN ra (Windows + R) => rồi nhập vào lệnh regedit => và bấm phím Enter để truy cập công cụ Registry Editor trên Windows 10.

Ngoài ra, bạn có thể nhấn Windows + S để mở Windows Search => sau đó nhập trực tiếp câu lệnh này vào ô tìm kiếm hoặc từ khóa Registry Editor thì cũng mở được công cụ này, mình thì quen dùng Windows RUN hơn vì nó đơn giản và tiện.

cach-tat-superfetch-sysmain-tren-windows-10 (2)

+ Bước 2: Sau đó, bạn truy cập vào thư mục Sysmain trong Registry của Windows 10 theo đường dẫn:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\SysMain

Bạn có thể dán trực tiếp đường dẫn này vào thanh địa chỉ của Registry Editor => rồi bấm Enter để truy cập nhanh hơn.

Nếu không thấy thanh địa chỉ như trong hình bên dưới, bạn hãy click vào chữ View trên thanh điều hướng ngang và chọn dòng Address Bar để hiển thị thanh địa chỉ nha.

cach-tat-superfetch-sysmain-tren-windows-10 (3)

+ Bước 3: Rồi ở trong thư Sysmain này, bạn sẽ thấy có rất nhiều các khóa quy định cách thức hoạt động của Superfetch trên Windows 10.

Theo như thông tin ở đây, Superfetch không có file thực thi *.exe cụ thể mà chỉ có file sysmain.dll nằm trong thư mục System32 và hoạt động được nhờ có các Service Host.

Quay trở lại vấn đề chính, hãy tìm trong danh sách này một khóa có tên Start, đây chính là khóa quy định trạng thái bật tắt của Superfetch trên Windows 10. Bạn hãy click chuột phải lên khóa này => rồi chọn Modify… để chính sửa giá trị của nó.

Mặc định khóa Start đã có sẵn trong Registry của Windows 10, nhưng trong trường hợp không thấy thì bạn hoàn toàn có thể tạo lại bằng cách:

Click chuột phải vào khoảng trống bất kỳ trong cửa sổ bên phải => chọn New => DWORD (32-bit) Value rồi đặt tên cho nó là Start và bắt đầu chỉnh sửa.

cach-tat-superfetch-sysmain-tren-windows-10 (4)

+ Bước 4: Cửa sổ Edit DWORD (32-bit) Value xuất hiện, chỉ chỉnh sửa giá trị trong ô Value data, những cái còn lại hãy giữ nguyên. Với Value data, chúng ta có 4 giá trị tương ứng với 4 trạng thái của dịch vụ Superfetch này bao gồm:

  • – Automatic (Delayed Start) – Tự động chạy nhưng chỉ khi Windows đã khởi động xong
  • – Automatic – Tự động chạy và khởi động đồng thời với Windows – Cái này là mình đang để như bạn thấy trong hình ở bên trên.
  •  Manual – Chỉ chạy khi bạn hoặc phần mềm nào đó khởi động nó lên.
  • 4 – Disabled – Tắt Superfetch

=> Vì trong bài viết này chúng ta đang muốn tắt Superfetch để sửa lỗi Full Disk, tăng tốc Windows 10 nên bạn hãy nhập vào ô Value data số 4 => rồi bấm OK để lưu lại.

cach-tat-superfetch-sysmain-tren-windows-10 (5)

+ Bước 5: Quá trình chỉnh sửa Registry đã hoàn tất, giờ bạn đã có thể đóng Registry Editor và khởi động lại máy khi có thể để các thay đổi vừa thực hiện có hiệu lực.

#2. Tắt Superfetch bằng lệnh trong CMD

Nếu như bạn không thích chỉnh sửa trong Registry vì sợ sai hoặc không rành về máy tính thì cũng có thể sử dụng vài dòng lệnh dưới đây trong cửa sổ Command Prompt.

Thực hiện:

Hãy mở Windows Run ra (Windows + R) => rồi nhập cmd và sử dụng tổ hợp phím Ctrl + Shift + Enter để mở CMD với quyền Admin, khuyến khích các bạn sử dụng cách này vì nó tiện 😀

cach-tat-superfetch-sysmain-tren-windows-10 (6)

Trước tiên, chúng ta cần dừng dịch vụ Superfetch lại để nó ngừng ngốn RAM và ổ cứng, và cũng vì không thể End Task trực tiếp bằng Task Manager được nên chúng ta mới phải sử dụng đến Command Prompt.

Nhập vào cửa sổ Command Prompt dòng lệnh sc stop "SysMain" => rồi bấm Enter để tạm dừng dịch vụ Superfetch, nếu thấy kết quả trả về như hình bên dưới là OK rồi đấy.

Còn nếu bạn thấy thông báo OpenService FAILED : Access is denied thì nhớ chạy lại Command Prompt với quyền Admin đi nha.

cach-tat-superfetch-sysmain-tren-windows-10 (7)

Cuối cùng, sử dụng lệnh sc config "SysMain" start=disabled để tắt hẳn dịch vụ Superfetch trên Windows 10.

Ngoài ra, bạn còn có thể thay disabled trong start bằng các tùy chọn khác như là boot, system, auto, demand, delayed-auto nữa.

Chạy xong sẽ xuất hiện dòng chữ [SC] ChangeServiceConfig SUCCESS như bên dưới là bạn đã tắt thành công dịch vụ Superfetch trên Windows 10 chỉ bằng 1 dòng lệnh rồi đó. Giờ bạn cũng cần khởi động lại máy tính để các thay đổi này có hiệu lực.

cach-tat-superfetch-sysmain-tren-windows-10 (8)

II. Lời kết

Như vậy là mình đã hướng dẫn xong cho các bạn tắt dịch vụ SysMain trên Windows để khắc phục lỗi Full Disk trên ổ cứng HDD rồi ha.

Nói chung, các bạn cũng nên đọc tham khảo thêm thôi chứ thực sự 2 cách mình vừa nêu trên không nhanh và tiện bằng cách dùng Service Manager như thông thường được.

CTV: Nguyễn Thanh Tùng – Bài viết gốc tại blogchiasekienthuc.com

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

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

Tìm hiểu về lệnh DIR [Directory] trong CMD [Command Prompt]

directory

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

Lệnh DIR là viết tắt của từ Directory. Đây là lệnh cho phép chúng ta xem và theo dõi các tệp, cũng như thư mục ở trong Folder mà bạn trỏ tới.

Vâng, và ở trong bài viết này chúng ta sẽ cùng tìm hiểu kỹ hơn về lệnh DIR trên hệ điều hành Windows nhé. Về toàn bộ các lệnh của DIR cũng như cách sử dụng lệnh DIR này.

  Cách sử dụng lệnh Xcopy trong CMD (Command Prompt)
  Cài đặt MySQL Community Server trên macOS

#1. Hướng dẫn cơ bản về lệnh Directory

Ví dụ khi mình chạy một lệnh DIR thì chúng ta có các mục như sau:

  • Màu đỏ: Hiển thị Ngày, tháng, năm của File hoặc Folder (tính cả việc tạo, copy hoặc move file hoặc folder vào thư mục này nha các bạn).
  • Màu cam: Thời gian File hoặc Folder xuất hiện trong thư mục.
  • Màu xanh lam: Đánh dấu cho ta biết đó là thư mục (Folder).
  • Màu tím: Dung lượng của tệp.
  • Màu xanh lá: Tên File hoặc Folder.
  • Màu vàng: Tên và mã số ổ cứng.

tim-hieu-ve-lenh-dir-directory-trong-cmd (1)

  • Màu trắng: Số lượng tệp và thư mục con trong Folder. Đồng thời liệt kê thêm dung lượng đang dùng và còn trống của ổ cứng chứa folder này.

tim-hieu-ve-lenh-dir-directory-trong-cmd (2)

Ví dụ cụ thể nhé: Bây giờ mình muốn xem tệp và thư mục trong Folder Server ở ổ D thì mình sẽ có 2 cách như sau:

Cách 1: Ví dụ ở đây mình muốn truy cập vào thư mục Server trong ổ D thì mình sẽ dùng lệnh như sau (sau mỗi lệnh bạn nhấn Enter nhé):

D:
cd Server
dir

tim-hieu-ve-lenh-dir-directory-trong-cmd (3)

Cách 2: Nhập lệnh dir đường-dẫn-của-thư-mục. Cụ thể ở đây là lệnh dir D:\Server

tim-hieu-ve-lenh-dir-directory-trong-cmd (4)

Vậy sẽ có bạn hỏi là: Hai cách trên sử dụng trong trường hợp nào? Thì đối với mình, cách đầu tiên sẽ sử dụng khi bạn làm nhiều việc với thư mục đó.

Ví dụ, sau khi dùng lệnh dir xong, bạn có thể sử dụng thêm các lệnh khác cho các tệp hoặc thư mục con trong đó.

Cách thứ hai tiện lợi hơn khi chỉ cần copy đường dẫn tới lệnh, tuy nhiên sẽ rất bất tiện nếu bạn muốn sử dụng thêm các lệnh khác cho tệp hoặc thư mục đó. Các bạn sử dụng linh động hai cách trên nha.

#2. Các lệnh nâng cao trong Directory

Ta có thể phân loại tệp hoặc thư mục theo thuộc tính. Có các thuộc tính sau:

  • Directories (d): Chỉ các thư mục con.
  • Read-only tệps (r): Chỉ các tệp hoặc thư mục chỉ đọc.
  • Hidden tệps (h): Chỉ các tệp hoặc thư mục bị ẩn.
  • System tệps (s): Chỉ các tệp hoặc thư mục hệ thống.
  • Not Directories (-d): Không liệt kê các thư mục con.
  • Not Read-only tệps (-r): Không liệt kê các tệp hoặc thư mục chỉ đọc.
  • Not Hidden tệps (-h): Không liệt kê các tệp hoặc thư mục bị ẩn.
  • Not System tệps (-s): Không liệt kê các tệp hoặc thư mục hệ thống.

2.1. Cách quản lý file trong Folder như sau, đây là công thức chung:

dir /a:“thuộc tính trong dấu ngoặc đơn” “Đường dẫn tệp (nếu chưa trỏ đến thư mục)”

_______________________

Ví dụ: Mình muốn lọc Folder Server của mình chỉ hiển thị các thư mục thì sẽ sử dụng lệnh sau đây:

dir /a:d “D:\Server” (Do mình đã trỏ Command Prompt tới thư mục Server nên không cần thêm đường dẫn D:\Server nữa).

=> Như các bạn đã thấy, CMD chỉ hiển thị các thư mục và bỏ qua tất cả các tệp trong thư mục rồi đó.

tim-hieu-ve-lenh-dir-directory-trong-cmd (5)

Lưu ý: Có thể kết hợp các thuộc tính với nhau. Ví dụ mình muốn lọc chỉ hiển thị các thư mục ẩn thì dùng lệnh sau:

dir /a:dh (d: hiển thị thư mục, h: hiển thị tệp và thư mục ẩn).

tim-hieu-ve-lenh-dir-directory-trong-cmd (6)

Như các bạn đã thấy, trong thư mục Server mình chỉ có thư mục con dungeon5 có thuộc tính ẩn nên dir chỉ hiển thị mỗi folder trên.

Không chỉ như vậy, lệnh dir còn cho phép ta thấy được chủ sở hữu của tệp hoặc thư mục bằng cách sử dụng lệnh:

dir /q

tim-hieu-ve-lenh-dir-directory-trong-cmd (7)

Như các bạn đã thấy ở hình bên trên, dir đã thêm một dòng cho mỗi tệp và thư mục là “DESKTOP-U7RQ5F1\~~~~~”.

Phần DESKTOP-U7RQ5F1 là tên máy tính, còn “~~~~~” là tên tài khoản tạo ra File và Folder này. (Tên hơi dị thông cảm cho mình nha :D).

2.2. Ta có thể sắp xếp các File hoặc thư mục theo các thứ tự sau bằng lệnh:

dir /o:”Tên-sắp-xếp”

Trong đó, tên sắp xếp bao gồm các loại như:

  • By Name (n): Theo tên (Bắt đầu tính từ chữ cái đầu là a-z).

tim-hieu-ve-lenh-dir-directory-trong-cmd (8)

  • By Size: (s): Theo kích cỡ file (Bắt đầu tính từ tệp có dung lượng nhỏ nhất).

tim-hieu-ve-lenh-dir-directory-trong-cmd (9)

  • By Extension (e): Theo phần mở rộng của tệp (Bắt đầu tính từ chữ cái đầu là a-z).

tim-hieu-ve-lenh-dir-directory-trong-cmd (10)

  • By Date/time (d): Theo thời gian (Bắt đầu tính từ tệp hoặc thư mục xuất hiện cũ nhất -> mới nhất).

tim-hieu-ve-lenh-dir-directory-trong-cmd (11)

  • Group Directories First (g): Liệt kê tất cả các thư mục trước, tệp sau.

tim-hieu-ve-lenh-dir-directory-trong-cmd (12)

Lưu ý: Bạn có thể thêm dấu (-) trước tên sắp xếp để đảo ngược lại sự sắp xếp của File hoặc Folder. Ví dụ mình muốn sắp xếp file lên trước, folder sau thì dùng lệnh sau:

dir /o:-g

tim-hieu-ve-lenh-dir-directory-trong-cmd (13)

Dir còn có thêm các lệnh như sau:

  • dir /d hoặc dir /w: Xem danh sách liệt kê theo chiều ngang.

tim-hieu-ve-lenh-dir-directory-trong-cmd (14)

  • dir /c: Cho phép ta hiển thị dấu phẩy sau mỗi hàng cho kích cỡ file (hàng nghìn, hàng trăm,…) và được bật mặc định.

tim-hieu-ve-lenh-dir-directory-trong-cmd (15)

  • dir /-c: Tắt hiển thị dấu phẩy cho kích cỡ file.

tim-hieu-ve-lenh-dir-directory-trong-cmd (16)

  • dir /b: Chỉ hiển thị tên file hoặc folder.

tim-hieu-ve-lenh-dir-directory-trong-cmd (17)

  • dir /p: Chỉ sử dụng cho file batch. Sau khi sử dụng xong lệnh sẽ cần bấm phím bất kì để tắt pop-up lệnh.

tim-hieu-ve-lenh-dir-directory-trong-cmd (18)

Okay, như vậy là mình đã hướng dẫn xong cho các bạn hầu như tất cả các lệnh DIR trên hệ điều hành Windows rồi nhé.

CTV: Hoàng Tuấn – Bài viết gốc tại blogchiasekienthuc.com

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

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

Bazel 4.1.0: Bài 1 – Cài đặt bazel 4.1.0

bazel
Cài đặt bazel 4.1.0

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

Bazel là gì?

Nói ngắn gọn:

  • Tool do Google viết, dùng để build các project iOS, android, C++… Trong bài viết này chúng tôi tập trung vào iOS.
  • Sử dụng với các project nhiều người làm, tránh conflict khi nhiều người cùng sửa file project xcode
  • Khi dùng bazel, mọi cài đặt trên Xcode đều vô nghĩa.
  • Mọi thứ cài đặt bằng bazel đều effect tới Xcode, y hệt như bạn cấu hình trên Xcode
  • Cấu hình bằng script, nên đòi hỏi dev phải kiên trì đọc tài liệu của nó.
  • Chọn version 4.1.0 vì nó hỗ trợ M1, và là phiên bản mới nhất tính đến thời điểm viết bài này(8/2021)
  Bộ cài đặt Laravel Installer đã hỗ trợ tích hợp Jetstream
  Cách cài đặt Android Studio phiên bản năm 2020

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

đầu tiên tải file sh của 4.1.0, bấm vào đây:

https://github.com/bazelbuild/bazel/releases/download/4.1.0/bazel-4.1.0-installer-darwin-x86_64.sh

Cho phép quyền thực thi. Bạn dùng terminal cd vào nơi chứa file vừa tải và gõ:

chmod +x bazel-4.1.0-installer-darwin-x86_64.sh

Sau đó gõ tiếp lệnh sau để cài đặt:

./bazel-4.1.0-installer-darwin-x86_64.sh

Cấu hình môi trường bằng lệnh:

export PATH="$PATH:$HOME/bin"

Kiểm tra version để confim là cài đặt thành công bằng lệnh:

bazel --version

Nếu nó ra chữ bazel 4.1.0 thì nghĩa là bạn đã cài đặt thành công.

Bạn có thể cài đặt phiên bản khác bằng cách kiểm tra các release của team bazel ở đây:

https://github.com/bazelbuild/bazel/releases

Lúc đó, phiên bản sẽ tương ứng với file name là bazel-<version>-installer-darwin-x86_64.sh, trong đó version là số hiệu phiên bản hiện có.

Cài đặt bằng Homebrew

Nếu thích Homebrew thì bạn cài như sau:

brew install bazel

Sau đó kiểm tra thành công chưa bằng cách gõ:

bazel --version

Tiếp theo nếu bạn muốn cập nhật lên phiên bản mới nhất của bazel thì gõ lệnh:

brew upgrade bazel

Nếu bạn đọc được tiếng Anh thì đây là phiên bản đầy đủ:

https://docs.bazel.build/versions/4.1.0/install-os-x.html

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 hấp dẫn trên TopDev

Hibernate Native SQL Queries

native sql queries
Hibernate Native SQL Queries

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

Trong Hibernate, HQL hoặc Criteria Query cho phép chúng ta thực hiện hầu hết mọi truy vấn SQL mong muốn. Tuy nhiên, đôi khi về câu lệnh SQL được tạo ra bởi Hibernate chậm hoặc cần viết câu lệnh phức tạp và thích tạo câu lệnh SQL (SQL gốc) của riêng mình hơn. Với Hibernate cho chúng ta sử dụng Native SQL để thao tác với cơ sở dữ liệu, bao gồm các stored procedures, và tất cả các thao tác create, update, delete và select.

Tương tự như HQL hay Creteria, để tạo đối tượng Native Query chúng ta sẽ sử dụng phương thức createNativeQuery() từ đối tượng Session:

org.hibernate.query.NativeQuery createNativeQuery(java.lang.String s); <R> org.hibernate.query.NativeQuery<R> createNativeQuery(java.lang.String s, java.lang.Class<R> aClass);

Scalar queries

Các truy vấn SQL cơ bản nhất là để có được một danh sách các giá trị scalars (column) từ một hoặc nhiều bảng.

Ví dụ lấy tất cả các column của bảng user.

NativeQuery query = session.createNativeQuery("SELECT * FROM user" ); List<Object[]> users = query.getResultList();

Ví dụ lấy fullname và email của 10 user từ vị trí thứ 5

NativeQuery query = session.createNativeQuery("SELECT username, password FROM user ORDER BY username" ); List<Object[]> users = query.setFirstResult(5).setMaxResults(10).getResultList(); users.forEach( user -> { System.out.println("username: " + user[0] + " | password: " + user[1]); });

Ví dụ lấy username và password của một user có id là 1

NativeQuery query = session.createNativeQuery("SELECT username, password FROM user where id = :id" ); Object[] user = (Object[]) query.setParameter("id", 1).uniqueResult(); System.out.println("username: " + user[0] + " | password: " + user[1]);
  "Làm PM, theo anh không cần biết về code, nhưng phải hiểu về SQL, database, những khái niệm cơ bản của code"
  Các thao tác cơ bản với Database SQL Server (tạo mới database, table,...)

Entity queries

Các truy vấn ở trên là về trả về các giá trị vô hướng từ ResultSet.

Ví dụ sử dụng JPA native query để có được các đối tượng Entity từ một truy vấn Native SQL

NativeQuery query = session.createNativeQuery("SELECT * FROM user", User.class ); List<User> users = query.getResultList();

Sau đây là cú pháp để có được các đối tượng Entity từ một truy vấn Native SQL thông qua addEntity().

NativeQuery query = session.createNativeQuery("SELECT * FROM user" ); List<User> users = query.addEntity(User.class).list();

Tìm việc làm lập trình SQL lương cao

DTOs (Data Transfer Objects)

Đôi khi chúng ta cần truy vấn một vài column và trả về trực tiếp cho đối tượng DTO, không cần phải thông qua Entity.

Ví dụ:

UserDTO.java

@Data public class UserDTO {     private String fullname;     private String username; }

Sử dụng ResultTransformer để trả về đượng tượng non-entity.

NativeQuery query = session.createNativeQuery("SELECT fullname, username FROM user" ); List<UserDTO> users = query.setResultTransformer( Transformers.aliasToBean( UserDTO.class ) ).list();

Nếu không muốn trả về DTO, có thể trả về một Map<String, Object> như sau:

NativeQuery query = session.createNativeQuery("SELECT fullname, username FROM user" ); List<Map<String,Object>> mapUsers = query.setResultTransformer(AliasToEntityMapResultTransformer.INSTANCE).list(); mapUsers.forEach( user -> { System.out.println(user.get("fullname")); });

Handling associations and collections

Ví dụ lấy thông tin user và user profile.

List<Object[]> tuples = session.createNativeQuery(         "SELECT * " +                 "FROM user u " +                 "INNER JOIN user_profile p ON u.id = p.user_id" )         .addEntity("user", User.class )         .addJoin( "p", "user.userProfile")         .list(); for(Object[] tuple : tuples) {     User user = (User) tuple[0];     UserProfile userProfile = (UserProfile) tuple[1];     System.out.println("fullname " + user.getFullname() + " | address " + userProfile.getAddress()); }

Mặc định khi sử dụng addJoin(), kết quả trả về sẽ bao gồm tất cả các entity được join trong 1 array. Để trả về một đối tượng entity hierarchy, chúng ta cần sử dụng ROOT_ENTITY hoặc DISTINCT_ROOT_ENTITY ResultTransformer.

Chi tiết về các truy vấn khác, các bạn tham khảo thêm link bên dưới.

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 IT hấp dẫn trên TopDev

Strategy pattern: vịt bảo, liên quan gì tới tao?

strategy pattern
Strategy pattern : vịt bảo, liên quan gì tới tao?

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

Một ngày đẹp trời, sếp giao cho Tồ ngồi code vài ba con vịt – chẳng liên quan gì tới Strategy Pattern. Vịt thì cũng không nhiều loại lắm (vịt nhựa, vịt trời và vịt nhà). Làm dev cái qq gì lại đi code vài ba con vịt. Rõ điên, tồ cay lắm.

Nhưng thôi, “ăn cơm chúa múa tối ngày”, không code có khi nó lại đuổi cmn mình mất. Tồ lọ mọ ngồi thiết kế class, kế thừa (inheritance) này nọ. Dự án kết thúc, Tồ lại về nhà, ăn ngon, ngủ yên.

3 tháng sau, dự án mantain, dự án thêm 30 loại vịt. Tồ mở code lên maintain, code thế này sao mở rộng được. Hướng thiết kế vừa khó sửa chữa, vừa mất thời gian. Tồ tìm hiểu ngay về STRATEGY PATTERN, cố gắng thiết kế lại. Thành công, tồ hiểu thêm về strategy, tiện viết luôn bài này chia sẻ cùng mọi người.

  Architectural Styles vs. Architectural Patterns vs. Design Patterns
  Building Microservices Application - Phần 2: Xử lý "Chain of Failures" dùng Circuit Breaker Pattern với Netflix Hystrix

1. Revisiting inheritance – một xíu về kế thừa.

Kế thừa (inheritance) là một bốn khái niệm quan trọng và cốt lõi của OOP (lập trình hướng đối tượng). Thông qua kế thừa, ta có thể tái sử dụng hoặc mở rộng hành vi (behavior), thuộc tính (properties) của lớp khác.

Khi kế thừa được sử dụng đúng đắn, code sẽ viết ít đi, các lớp (class) trở nên linh động (flexible). Việc một đối tượng có thể được kế thừa hay không chủ yếu tới từ IS-A (là cái gì).

Ví dụ: Mèo là động vật -> nó nên thuộc về lớp Animal. Mà giờ có khi lại thuộc cmn lớp Boss (vì nó như bố của đứa nuôi nó) =)).

Mặc dù kế thừa là khái niệm quan trọng, lạm dụng kế thừa lại không hề tốt. Nếu thiết kế các lớp kế thừa không tốt, code sẽ trở nên cực kì rối rắm. Các lớp kế thừa được thiết kế nhiều, nhưng các lớp con lại không thể sử dụng linh hoạt, đó là chưa nói tới các đoạn code phải lặp đi lặp lại nhiều lần.

2. Limit of inheritance – hạn chế của việc kế thừa.

Lấy ví dụ như sau: có 3 loại vịt (vịt trời, vịt nhà, vịt nhựa). Cả ba đều kế thừa lớp Vịt. Thiết kế lớp để kế thừa của ta ban đầu được thiết kế như sau:

strategy-pattern

Cả vịt nhưa, vịt trời và vịt nhà đều override lại method display() từ class cha. Tuy nhiên, chỉ có vịt trời và vịt nhà là thật sự biết kêu (quack). Chà, thiết kế còn tốt chán. Trông ra thì cũng chả có vấn đề gì to tát ở đây cả.

Tuy nhiên, một ngày đẹp trời, class cha Duck thêm vào method fly(), tất nhiên, trong họ nhà vịt thiếu gì con biết bay.

strategy-pattern

Đệch, vịt nhựa thì chắc chắn là không bay được, vì vậy phải override lại method này. Hơn nữa, còn phải chắc chắn rằng trong method override này không làm gì cả (do nothing). Sự thật là thế, con vịt nhựa mà bay được thì code sai tè le mất rồi. =))).

Không thể cứ class nào cùng overide method.

Nếu class cha có tới 15 method thì sao, chả nhẽ method nào cũng phải override lại?. Tới đây, hạn chế của kế thừa đã lộ rõ, các đoạn code kế thừa ở các lớp con lặp đi lặp lại. Đã không dùng lại phải thêm một đống code vào class. Thật sự tệ. Một thay đổi nhỏ ở lớp cha (super class) cũng kéo theo việc phải thay đổi code ở các lớp con kế thừa nó.

Hừm, để nghĩ xem. À, còn interface, sao không tách m* 2 cái fly và quack ra thành interface. Ngon.

3. Trying interface – thử dùng interface

Đm, học hành phỏng vấn đã lâu, nay đã đùng được interface, thật đáng công sức. Tách ra thế này.

strategy-pattern

Đầu tiên, 2 method fly() và quack() sẽ được tạo thành 2 interface riêng (flyable và quackable). Vịt trời và vịt nhà sẽ implement hai inteface này. Vịt nhựa thì do không bay cũng không kêu, nên nó không implements cái nào.

Chà, nghĩ chút, thiết kế này trông có vẻ ổn. Nếu lớp Duck sau này có thêm method fly(), thì chỉ cần tạo thêm interface Flyable nữa.

Lúc sử dụng thì con vịt nào cần cái nào thì nó implement cái đó.

Mà khoan. Trường hợp có 30 hay 40 lớp vịt thì như thế nào?

Đệch, cả 30, 40 cái class cùng implement quack và fly (hầu như mấy loài vịt khác con nào chả kêu, con nào chả bay). Lúc có thì, bất cứ thay đổi gì (cho dù là nhỏ) trong phương thức fly(), các class implement đều sửa. Maintenance code kiểu này thật sự là ác mộng (nightmare).

strategy-pattern-disadvan

Thiết kế kiểu này xem ra không ổn -> mấy thằng dev sau nó vào đọc code mà đi mainte chắc nó chửi chết. Thôi đành xuất chiêu cuối, sử đụng strategy pattern.

4. Apply the principle – chốt hạ dùng Strategy pattern

Không thể để hậu nhân chửi bới được. Thiết kế chuẩn chỉnh lại theo strategy pattern thôi.

Để xem, vẫn có hai cái interface được tách ra (fly behavior, quack behavior).

strategy-pattern

Tuy nhiên, cái hay của strategy pattern là không phải lũ vịt sẽ implement trực tiếp các interface này. Ta sẽ viết các subclass implement. Cụ thể là:

strategy-pattern

Các class implements sẽ được tách ra theo behavior. Hai class implement fly behavior là flyWithWings (bay được) và flyNoWay (không bay được).

// Fly behavior implement.
public class FlyWithWings implements FlyBehavior {
public void fly() {
System.out.println('Hura, tao có thể bay');
}
}
// Fly behavior implement.
public class FlyNoWay implements FlyBehavior {
public void fly() {
System.out.println('ĐM, tao đéo bay được');
}
}

Quack thì có 2 class Quack (kêu được), Mute (không kêu được).

// Quack behavior implement.
public class Quack implements QuackBehavior {
public void quack() {
System.out.println('Tao kêu được');
}
}
public class Mute implements QuackBehavior {
public void mute() {
System.out.println('Tao đéo kêu được');
}
}

Khúc quan trọng đây rồi. Khi đã có các class cụ thể implements từ interface. Công việc còn lại là viết abtract class Duck cho tất cả lũ vịt extends.

// Fly behavior implement.
public abstract class Duck {
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
// Con nào cũng hiển thị
abstract void display();
public Duck() {};
// Fly
public void performFly() {
flyBehavior.fly();
}
// Quack
public void performQuack() {
quackBehavior.quack();
}
}

Ngon lành cành đào, lúc khởi tạo class mới, ví dụ như vịt trời, chỉ cần new constructor theo behavior cho nó. Tất nhiên sẽ extends class Duck.

// Vit troi class.
public class VitTroi extends Duck {
// Constructor instance
public VitTroi() {
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
}
}

Đối với vịt nhựa, do vịt nhựa không kêu cũng không bay, nên instance của nó sẽ là Mute và FlyNoWay.

// Vit nhua class.
public class VitNhua extends Duck {
// Constructor instance
public VitNhua() {
quackBehavior = new Mute();
flyBehavior = new FlyNoWay();
}
}

Cuối cùng, class Vịt chỉ đơn giản gọi các method được perform là quack và fly.

// Vit troi class.
public class Vit {
public static void main(String[] args) {
// Vit troi
Duck vitTroi = new VitTroi();
vitTroi.performQuack();
vitTroi.performFLy();

// Vit nhua
Duck vitNhua = new VitNhua();
vitNhua.performQuack();
vitNhua.performFly();
}
}

5. Kết luận

Strategy pattern rõ ràng là một thiết kế tốtTại sao lại thế?. Mặc dù vẫn sử dụng các interface. Tuy nhiên, với mô hình strategy, các interface sẽ được xác định rõ chức năng của nó (thông qua các behavior – class implements FlyNoWays, FlyWithWings, …). Trường hợp có sửa đổi hay thêm mới ta không cần sửa tới các interface, mỗi loài vịt đều có các class riêng đặc trưng khả năng của nó.

Trường hợp lũ vịt có thêm các method mới, đơn giản chỉ cần thêm các class behavior. Các class này độc lập, rất thuận tiện cho việc sửa đổi sau này.

Lúc maintain code, có thể dễ dàng bổ sung class implement các behaviors. Việc sửa đổi hay thêm mới class không hề làm ảnh hưởng tới các loài vịt khác.

Rõ ràng, stategy pattern đem tới một thiết kế không tồi tẹo nào. =))

Trên đây là hiểu biết cá nhân và ý kiến riêng của mình về strategy pattern. Rất mong nhận được phản hồi từ các bạn. Ngoài ra, các bạn có thể tham khảo thêm bài viết về JVM architecture.

6. Tham khảo

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

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

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

Lỗi Could not create the Java Virtual Machine khi chạy Minecraft

minecraft
Lỗi Could not create the Java Virtual Machine khi chạy Minecraft

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

Có bao giờ bạn gặp một thông báo lỗi như thế này chưa? (lỗi này xảy ra khi mình chạy game Minecraft).

Error: Could not create the Java Virtual Machine.
Error: A fatalexception has occurred. Program will exit.

loi-could-not-create-the-java-virtual-machine (1)

Mình nghĩ là lỗi này chắc nhiều bạn cũng đã từng bị rồi. Chính vì thế mà hôm nay mình sẽ hướng dẫn cho các bạn các cách để sửa lỗi này một cách hiệu quả nhất nhé.

  10 lý do cho thấy tại sao bạn nên theo học ngôn ngữ lập trình Java
  10 tips để trở thành Java Developer xịn hơn

Xem thêm nhiều việc làm Java lương cao trên TopDev

#1. Tạo một System Variable cho Java

Đầu tiên bạn nhấn tổ hợp phím Windows + R để mở hộp thoại Run => sau đó nhập sysdm.cpl => và bấm OK.

loi-could-not-create-the-java-virtual-machine (2)

Tiếp theo, bạn vào tab Advanced => và bấm vào Environment Variables trong phần Startup and Recovery.

loi-could-not-create-the-java-virtual-machine (3)

Sau đó bạn tiếp tục bấm vào New ở phàn System Variables.

loi-could-not-create-the-java-virtual-machine (4)

Sau đó bạn thiết lập như sau:

  • Variable name bạn nhập JAVA_OPTIONS
  • Variable value bạn nhập là –Xmx512M để xác định số lượng RAM tối đa mà Minecraft có thể sử dụng, ở trong ví dụ này mình để là 512MB. Bạn có thể thay đổi thành –Xmx1024M hoặc –Xmx2048M.

=> Cuối cùng bạn bấm OK để thực hiện.

loi-could-not-create-the-java-virtual-machine (5)

#2. Chạy Java với quyền Admin

Để thực hiện điều này thì bạn nhấn tổ hợp phím Windows + S để mở Windows Search => sau đó nhập từ khóa tìm kiếm là Java.

Nếu như có sẵn shorcut Java ở ngoài màn hình Desktop thì nhấn chuột phải vào shortcut đó luôn.

Bấm chuột phải vào kết quả mà nó tìm thấy => sau đó nhấn vào Open file location để truy cập vào thư mục cài đặt Java.

=> Tiếp theo bạn bấm chuột phải vào file java.exe => và chọn Properties.

loi-could-not-create-the-java-virtual-machine (1)

Bạn chuyển sang tab Compatibility => sau đó bạn tick vào phần Run this program as an administrator. Cuối cùng bấm Apply => OK để kết thúc.

loi-could-not-create-the-java-virtual-machine (2)

#3. Cài đặt lại Java

Cài đặt lại Java đôi khi cũng là một cách để sửa lỗi này. Có thể Java của bạn đã bị lỗi khi cài đặt. Bạn cũng nên tải về bản Java Offline để tránh bị lỗi khi cài đặt nha.

#4. Lời kết

Ok, như vậy là mình đã hướng dẫn xong cho các bạn cách để sửa lỗi Could not create the Java Virtual Machine trên hệ điều hành Windows rồi nhé.

Dù là thành công hay thất bại thì các bạn cũng đừng quên để lại comment bên dưới để anh em trao đổi thêm nhé. Thank you !

CTV: Hoàng Tuấn – Bài viết gốc tại blogchiasekienthuc.com

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

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

Todo List: Xóa dữ liệu từ database

xóa dữ liệu
Xóa dữ liệu từ database

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

Video trong bài viết

Khi làm việc với database người ta thường nhắc đến CRUD là một cụm từ viết tắt của 4 chức năng cần và đủ để tương tác với các bản ghi là Create, Read, Update và Delete. Cho đến bài học hôm nay, bạn đã được tìm hiểu về 3 chức năng đầu và giờ là lúc chúng ta cùng tìm hiểu phần còn lại, chức năng xóa dữ liệu.

  "Làm PM, theo anh không cần biết về code, nhưng phải hiểu về SQL, database, những khái niệm cơ bản của code"
  Các thao tác cơ bản với Database SQL Server (tạo mới database, table,...)

Xem thêm nhiều việc làm Database hấp dẫn trên TopDev

Tại sao phải xóa dữ liệu

Những dữ liệu không cần thiết chúng ta cần phải xóa khỏi database hoặc ít ra thì cũng không hiển thị trên ứng dụng, làm như vậy khi hiển thị các danh sách bản ghi với người dùng sẽ ngắn hơn và người dùng có thể bao quát hoặc tìm kiếm dễ dàng hơn. Có hai loại xóa dữ liệu:

  • Xóa dữ liệu ra khỏi database, dữ liệu sẽ không có khả năng xem lại khi cần thiết. Cách xóa này chỉ áp dụng với dữ liệu thông thường không quá quan trọng.
  • Xóa dữ liệu tạm thời bằng cách đánh dấu bằng các cờ xóa dữ liệu, cách này thường áp dụng cho các dữ liệu quan trọng, ví dụ dữ liệu tài chính, bạn có thể xóa một hợp đồng nhưng vẫn xem được chi tiết hợp đồng này nếu cần.

Trong ứng dụng Todo List, chúng ta sẽ sử dụng cách thứ nhất, xóa hẳn các bản ghi công việc cần làm khỏi database. Cách hai sẽ được giới thiệu đến các bạn trong một khóa học khác về Laravel.

Xóa dữ liệu trong ứng dụng Todo List

Quay trở lại với Quy trình 3 bước, hẳn bạn còn nhớ ở các bài trước chứ? Đường dẫn xóa một bản ghi Todo (giả sử id=3) sẽ có dạng /todos/3/delete. Chúng ta cùng thực hiện nhé.

Bước 1: Đăng ký đường dẫn

Trong các bài viết, các bước này cố tình được lặp đi lặp lại để các kiến thức này có thể được nhớ lâu hơn. Mở file routes/web.php và đăng ký đường dẫn xóa bản ghi:

Route::get('todos/{todo}/delete', 'TodosController@destroy');

Bước 2: Xử lý nghiệp vụ trong TodosController

Trong đăng ký ở bước 1, để xử lý cho đường dẫn xóa bản ghi là phương thức destroy() của TodosController. Thực hiện thêm phương thức này vào file app\Http\Controllers\TodosController.php:

public function destroy($todoId)
{
    $todo = Todo::find($todoId);
    $todo->delete();
    return redirect('/todos');
}

Công việc đơn giản là tìm Todo từ ID có được từ đường dẫn, thực hiện xóa bản ghi này bằng phương thức delete().

Bước 3: Hành động hoàn thành

Sau khi đã xóa xong bảng ghi, chúng ta chuyển hướng người dùng về trang danh sách todos.

Như vậy, chức năng xóa dữ liệu đã hoàn thành, tuy nhiên chúng ta chưa có một nút hoặc một đường link nào đó để bấm vào mỗi khi cần xóa, chẳng lẽ gõ thẳng đường dẫn để xóa một Todo nào đó? Chúng ta sẽ thêm một nút Delete vào trang chi tiết của Todo (view show). Mở resources/views/todos/show.blade.php và thêm vào nút Delete:

@extends('layouts.app')

@section('title')
    Single Todo: {{ $todo->name }}
@endsection

@section('content')
    <h1 class="text-center my-5">
        {{ $todo->name }}
    </h1>

    <div class="row justify-content-center">
        <div class="col-md-6">
            <div class="card card-default">
                <div class="card-header">
                    Details
                </div>

                <div class="card-body">
                    {{ $todo->description }}
                </div>
            </div>
            <a href="/todos/{{ $todo->id }}/edit" class="btn btn-info my-2">Edit</a>
            <a href="/todos/{{ $todo->id }}/delete" class="btn btn-danger my-2">Delete</a>
        </div>
    </div>
@endsection

Chức năng xóa dữ liệu

Source code: Bài 14 – Xóa dữ liệu từ database

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

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

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

Browser renders website như thế nào?

Browser renders website
Browser renders website như thế nào?

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

Đã là lập trình viên, hẳn sẽ có đôi lần bạn nghe qua về DOM, nhưng liệu rằng bạn có biết cây DOM đóng vai trò gì khi trình duyệt hiển thị nội dung?. Ngoài DOM tree còn những loại tree nào được build khi trình duyệt render một website?. Ôi, vô vàn câu hỏi vì sao, nhưng túm váy lại, bài viết này sẽ trả lời cho câu hỏi browser renders website như thế nào?.

Nội dung trang web chúng ta hằng ngày vẫn thường xem được vẽ (paint) ra sao?. Tất cả những câu hỏi này sẽ có trong bài viết sau đây

1. DOM – Document object model

Khi trình duyệt đọc được resource, trước khi browser renders website, nó sẽ có được dữ liệu từ HTML. Cụ thể, các tag html, body, div, … Từng đối tượng sẽ được tạo ra như một Javascript objects – gọi là Node.

Ủa, vậy node là gì?. Node có phải là class cuối cùng của instance các HTML tag không?. Câu trả lời là có. Một node object cho tag div sẽ được tạo từ HTMLDivElement (kế thừa từ class Node).

À, tới đây ta có thể hiểu thêm một phần về cách browser renders website . Trình duyệt sẽ new một loạt các instance theo các thẻ được cung cấp ở HTML. HTMLDivElement, HTMLScriptElement, Node, …

Xem thêm các việc làm Web/Mobile lương cao trên TopDev

Sau khi browser đã khởi tạo xong các instance của node, nó sẽ tiến hành build
tree-like structure của những node đã được tạo. Nói tóm lại, toàn bộ nội dung HTML phía server cung cấp sẽ được xây dựng thành DOM Tree

“Using DOM API, developers can add or remove HTML elements, change its appearance or bind event listeners. Using DOM API, HTML elements can be created or cloned in memory and maniuplated without affecting the rendered DOM tree. This gives developers the ability to construct highly dynamic web page with rich user experience.” – How the browser renders a web page?

“Sử dụng DOM API, lập trình viên có thể thêm hoặc xóa các đối tượng HTML, thay đổi cách mà nó xuất hiện, hoặc gán các event listeners. Sử dụng DOM API, HTML elements có thể khởi tạo hoặc sao chép vào trong bộ nhớ, thay đổi nhưng không nhất thiết phải render lại cây DOM. Điều này đem tới cho các lập trình viên khả năng xây dựng các website có trải nghiệm người dùng tốt”.

2. CSSOM- CSS object model

Từ lúc thiết kế website, tất nhiên ai cũng muốn website của mình đẹp nhất có thể. Bằng cách nào? -> dùng css. Vậy mỗi element trên HTML đều sẽ gắn liền với một CSS selector nhất định. Ví dụ như thẻ h1 có font-size, color. Những thứ này sẽ được xây dựng lên thành CSSOM.

Theo thứ tự, sau khi xây dựng cây DOM, browser renders website sẽ đọc toàn bộ nội dung CSS từ tất cả các nơi (external, embedded, inline, user-agent). Từ những nội dung này, browser dựng lên CSSOM (với cấu trúc tương tự như DOM tree).

Lấy ví dụ, với nội dung CSS được mô tả như sau:

html {
padding: 0;
margin: 0;
}body {
font-size: 14px;
}.container {
width: 300px;
height: 200px;
color: black;
}.container > h1 {
color: gray;
}.container > p {
font-size: 12px;
display: none;
}

Sau khi đọc được toàn bộ nội dung, browser sẽ dựng lên cây CSSOM như sau:

CSSOM tree được browser render sau khi đọc được nội dung CSS

3. Render Tree

Khi đã có cả DOM tree và CSSOM tree, đây là một trong những bước mà browser renders website. Bước này browser sẽ combined cả hai tree lại với nhau. Nội dung của 2 cây này sẽ cho ta thứ tự các nội dung trên website.

Một khi đã xây dựng xong reder tree, browser sẽ thực hiện vẽ từ element – đây là thứ mà chúng ta nhìn thấy. Nếu một node có CSSOM là display:none, hiển nhiên object này sẽ có kích thước 0px 0 0px -> không xuất hiện.

Các bước mà browser tạo ra Render-tree (nội dung website mà chúng ta thấy trên trình duyệt)

Lưu ý rằng, trong một số trường hợp, khi xây dựng cây combined giữa DOM và CSSOM, một số tag sẽ bị bỏ qua (vị dụ như tag meta, script, …). Một số node trên cây sẽ được ẩn đi (nếu CSS được viết với display:none).

  Cách để npm packages chạy trong browser
  Câu hỏi phỏng vấn mẹo về React: Component hay element được render trong browser?

4. Rendering sequence

Đọc tới đây, khi đã có cái nhìn khách quan về DOM, CSSOM và Render Tree, ta sẽ tiếp tục tìm hiểu về các bước (step) mà browser renders website.

4.1 Layout

Sau khi đã có nội dung mô tả chính xác các phần tử trên cây, trình duyệt sẽ thực hiện tính toán không gian cần thiết cho từng phần tử, vị trí của chúng ở trên màn hình.

4.2 Paint

Paint là quá trình trình duyệt vẽ từng pixel lên màn hình. Việc vẽ cũng được thực hiện trên nhiều lớp nếu như cần thiết (match color, layer hay phối màu)

4.3 Composite

Ở bước cuối cùng, browser kết hợp các layer lại với nhau, cho ta một cài nhìn hoàn chỉnh về website.

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

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

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

Bộ guide để viết code sạch dành riêng cho Vue

viết code sạch
Bộ guide để viết code sạch dành riêng cho Vue

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

Trước tiên cần thống nhất quan điểm thế này, ko phải guide nào cũng phù hợp cho mọi team, mọi dự án, nến không nhất thiết phải áp dụng một cách cứng nhắc trong mọi trường hợp

  3 phút làm quen với Vue.js
  API Authentication trong Laravel-Vue SPA sử dụng Jwt-auth

Xem thêm các chương trình tuyển dụng VueJS hấp dẫn trên TopDev

Cấp độ: Siêu cần thiết, giúp tránh được nhiều lỗi

Tên component nên là 2 chữ

Trừ App component và các component có sẵn trong Vue như <transition/><component />

Để tránh trùng các thẻ html, có thể sau này, HTML sẽ bổ sung thêm nhiều thẻ mới, thẻ HTML sẽ là 1 chữ

❌ Không ngon
Vue.component('todo', {
	//...
})

export default {
	name: 'Todo'
}

✅ Chuẩn cơm mẹ nấu
Vue.component('todo-item', {
	// ...
})

export default {
	name: 'TodoItem',
}

data phải là một function

data phải là function trả về object. Nếu là một object, tất cả các instance component sẽ cùng trỏ tới một dữ liệu data.

❌ Không ngon
export default{
	data: {
		foo: 'bar'
	}
}  

✅ Chuẩn cơm mẹ nấu
export default {
	data() {
		foo: 'bar'
	}
}

Riêng với thằng root component, nó chỉ có một, nên có thể là object

Khai báo prop càng chi tiết càng tốt

Ít nhất là có type, nếu được càng chi tiết chừng nào tốt chừng đó

❌ Không ngon
props: {
	status: String
}

✅ Chuẩn cơm mẹ nấu
props: {
	status: {
		type: String,
		required: true,
		validator: function (value) {
			return [
				'syncing',
				'synced',
				'version-conflict',
				'error'
			].indexOf(value) !== -1
		}
	}
}

Luôn cung cấp key cho v-for

Có luôn cái video này rồi, bạn xem ở đây

❌ Không ngon
<ul>
	<li v-for="todo in todos">
		{{ todo.text }}
	</li>
</ul> 

✅ Chuẩn cơm mẹ nấu
<ul>
	<li
		v-for="todo in todos"
		:key="todo.id"
	>
		{{ todo.text }}
	</li>
</ul>

Không bao giờ dùng v-for chung với v-if

Vì v-for được ưu tiên cao hơn v-if, nghĩa là nếu viết

❌ Không ngon

<ul>
	<li
		v-for="user in users"
		v-if="user.isActive"
		:key="user.id"
	>
		{{ user.name }}
	</li>
</ul>

Nó sẽ chạy như thế này

this.users.map(function (user) {
	if (user.isActive) {
		return user.name
	}
})

Nghĩa là cứ mỗi lần re-render chúng ta đều loop qua tất cả các phần tử trong mảng, trong khi giá trị isActive này không đổi, nó ko tối ưu

Nên filter trước các user có giá trị isActive = true trước

✅ Chuẩn cơm mẹ nấu
computed: {
	activeUsers: function () {
		return this.users.filter(function (user) {
			return user.isActive
		})
	}
}

CSS scoped trên từng component

Những style nào dùng global có thể đưa vào App component, còn trong từng component, luôn dùng kiểu scoped

Tuy nhiên nếu bạn đang làm 1 thư viện component, để dùng tới dùng lui, hay đưa lên npm cho người khác xài, nên dùng cùng css class bình thường, không có scoped, người khác sử dụng có thể dễ override lại nếu cần

❌ Không ngon
<template>
	<button class="btn btn-close">X</button>
</template>

<style>
	.btn-close {
		background-color: red;
	}
</style>

✅ Chuẩn cơm mẹ nấu
<template>
	<button class="button button-close">X</button>
</template>

<!-- Using the `scoped` attribute -->
<style scoped>
.button {
	border: none;
	border-radius: 2px;
} 

.button-close {
	background-color: red;
}
</style>

Dùng BEM khi viết thư viện component

<template>
	<button class="c-Button c-Button--close">X</button>
</template>

<!-- Using the BEM convention -->
<style>
.c-Button {
	border: none;
	border-radius: 2px;
}

.c-Button--close {
	background-color: red;
}
</style>

Private

Sử dụng module scope cho các function muốn private. Nếu không thể, luôn dùng tiền tố $_ trước các property private trong plugin, mixin,… và thêm luôn tên plugin để tránh bị conflict với các plugin khác ( $_yourPluginName_)

❌ Không ngon
var myMixin = {
	// ...
	methods: {
		update: function () {
			// ...
		},
		_update: function () {
			// ...
		},
		$update: function () {
			// ...
		}
		$_update: function () {
			// ...
		}
	}
}

✅ Chuẩn cơm mẹ nấu
var myMixin = {
	methods: {
		$_myMixin_update: function () { }
	}
}

Cấp độ: Cực kỳ khuyến khích

Một component là một file

👎 Chuẩn cơm mẹ nấu
Vue.component('TodoList', {
	// ...
})

Vue.component('TodoItem', {
	// ...
})

✅ Chuẩn cơm mẹ nấu
components/
|- TodoList.vue
|- TodoItem.vue

File name luôn là một trong 2 dạng PascalCase hoặc kebab-case

❌ Không ngon
components/
|- mycomponent.vue
components/
|- myComponent.vue  

✅ Chuẩn cơm mẹ nấu
components/
|- MyComponent.vue
components/
|- my-component.vue

Base component

Những component được dùng với mục đích đồng nhất styling, layout được gọi là base component, nó có thể chỉ chứa

  • HTML
  • UI component từ các thư viện khác
  • Các base component khác

Và không được chứa state của Vuex store

Tên nên được đặt theo kiểu BaseButtonBaseTable. Lợi ích của việc này

  • Khi mở trong editor, nó được liệt kê gần nhau, dễ tìm, dễ phân loại
  • Tên component sẽ luôn có 2 chữ như đã nói ở trên
  • Các component này được sử dụng rất thường xuyên, nên có thể dùng prefix để đăng ký một lần một cho tất cả component
var requireComponent = require.context("./src", true, /^Base[A-Z]/)
requireComponent.keys().forEach(function (fileName) {
var baseComponentConfig = requireComponent(fileName)
baseComponentConfig = baseComponentConfig.default || baseComponentConfig
var baseComponentName = baseComponentConfig.name || (
	fileName
	.replace(/^.+\//, '')
	.replace(/\.\w+$/, '')
)
Vue.component(baseComponentName, baseComponentConfig)
})
❌ Không ngon
components/
|- MyButton.vue
|- VueTable.vue
|- Icon.vue 

✅ Chuẩn cơm mẹ nấu
components/
|- BaseButton.vue
|- BaseTable.vue
|- BaseIcon.vue  

components/
|- AppButton.vue
|- AppTable.vue
|- AppIcon.vue

components/
|- VButton.vue
|- VTable.vue
|- VIcon.vue

Component chỉ có một instance duy nhất

Với những component chỉ xuất hiện một lần trên 1 trang, không bao giờ nhận prop. Chúng ta có một cách đặt tên riêng, thêm tiền tố The

❌ Không ngon
components/
|- Heading.vue
|- MySidebar.vue

✅ Chuẩn cơm mẹ nấu
components/
|- TheHeading.vue
|- TheSidebar.vue

Component luôn gắn chặt vào một component cha

Nếu một component con, luôn đi cùng một component cha nhất định, thêm tên component cha làm tiền tố

Một số người sẽ dùng cách đưa các component này vào trong thư mục con

components/
|- TodoList/
|- Item/
|- index.vue
|- Button.vue
|- index.vue

hoặc 

components/
|- TodoList/
|- Item/
|- Button.vue
|- Item.vue
|- TodoList.vue

Cách này ko được khuyến khích, vì nó có quá nhiều trùng tên, việc chuyển qua lại giữa các file này trong editor rất khó chịu, vì ko biết đang mở file nào, nhiều thư mục như vậy, làm việc duyệt qua các component này cũng mệt

❌ Không ngon
components/
|- TodoList.vue
|- TodoItem.vue
|- TodoButton.vue

components/
|- SearchSidebar.vue
|- NavigationForSearchSidebar.vue  

✅ Chuẩn cơm mẹ nấu
components/
|- TodoList.vue
|- TodoListItem.vue
|- TodoListItemButton.vue 

components/
|- SearchSidebar.vue
|- SearchSidebarNavigation.vue

Sử dụng kebab-case trong DOM template

Tên file của component thì nên viết dạng PascalCase, còn trong template nên dùng kebab-case

❌ Không ngon
<!-- In single-file components and string templates -->
<mycomponent/>

<!-- In single-file components and string templates -->
<myComponent/>  

<!-- In DOM templates -->
<MyComponent></MyComponent>

✅ Chuẩn cơm mẹ nấu
components/
<!-- In single-file components and string templates -->
<MyComponent/>

<!-- In DOM templates -->
<my-component></my-component>
 
OR 

<!-- Everywhere -->
<my-component></my-component>
❌ Không ngon
Vue.component('myComponent', {
	// ...
})

import myComponent from './MyComponent.vue'
export default {
	name: 'myComponent',
	// ...
}

export default {
	name: 'my-component',
	// ...
}

✅ Chuẩn cơm mẹ nấu
components/
Vue.component('MyComponent', {
	// ...
}) 

Vue.component('my-component', {
	// ...
})

import MyComponent from './MyComponent.vue'
export default {
	name: 'MyComponent',
	// ...
}

Đặt tên prop

Dùng camelCase lúc khai báo, kebab-case trong template

❌ Không ngon
props: {
	'greeting-text': String
}

<WelcomeMessage greetingText="hi"/>

✅ Chuẩn cơm mẹ nấu
props: {
	greetingText: String
}
	
<WelcomeMessage greeting-text="hi"/>

📜 Style Guide

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

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

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

Kết nối JMS Client với ActiveMQ

kết nối jms client
Kết nối JMS Client với ActiveMQ

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

Trong bài này, chúng ta sẽ cùng tìm hiểu cách tạo JMS Client (Producer và Consumer) để kết nối đến ActiveMQ server, cũng như sự khác biệt trong việc phân phối tin nhắn giữa Queue va Topic.

Tạo ActiveMQ project

Tạo maven project và mở file pom.xml, khai báo dependency như sau:

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">     <modelVersion>4.0.0</modelVersion>     <groupId>com.gpcoder</groupId>     <artifactId>activemq-example</artifactId>     <version>1.0-SNAPSHOT</version>     <properties>         <java.version>1.8</java.version>         <maven.compiler.target>1.8</maven.compiler.target>         <maven.compiler.source>1.8</maven.compiler.source>     </properties>     <dependencies>         <!-- https://mvnrepository.com/artifact/org.apache.activemq/activemq-client -->         <dependency>             <groupId>org.apache.activemq</groupId>             <artifactId>activemq-client</artifactId>             <version>5.15.12</version>         </dependency>         <!-- https://mvnrepository.com/artifact/org.apache.qpid/qpid-jms-client -->         <dependency>             <groupId>org.apache.qpid</groupId>             <artifactId>qpid-jms-client</artifactId>             <version>0.50.0</version>         </dependency>     </dependencies>     <build>         <plugins>             <!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-compiler-plugin -->             <plugin>                 <groupId>org.apache.maven.plugins</groupId>                 <artifactId>maven-compiler-plugin</artifactId>                 <version>3.8.1</version>                 <configuration>                     <source>1.8</source>                     <target>1.8</target>                 </configuration>             </plugin>             <!-- include all the dependencies into the jar for easier to execute the application -->             <!-- https://mvnrepository.com/artifact/org.fusesource.mvnplugins/maven-uberize-plugin -->             <plugin>                 <groupId>org.fusesource.mvnplugins</groupId>                 <artifactId>maven-uberize-plugin</artifactId>                 <version>1.45</version>                 <executions>                     <execution>                         <phase>package</phase>                         <goals>                             <goal>uberize</goal>                         </goals>                     </execution>                 </executions>             </plugin>         </plugins>     </build> </project>

Chúng ta chỉ cần sử dụng 1 trong 2 thư viện JMS Client: activemq-client hoặc qpid-jms-client. Trong bài này, tôi muốn giới thiệu với các bạn cả 2, nên cần include cả 2 thư viện này.

  • activemq-client : nếu muốn kết nối thông qua giao thức TCP.
  • qpid-jms-client : nếu muốn kết nối thông qua giao thức AMQP.
  Cài đặt ActiveMQ
  Bộ cài đặt Laravel Installer đã hỗ trợ tích hợp Jetstream

Tạo Producer và Consumer

Kết nối JMS Client với ActiveMQ

Tạo Producer

Các bước thực hiện:

  • Tạo ConnectionFactory : xác định remote URI đến ActiveMQ server. ActiveMQ hỗ trợ nhiều loại giao thức khác nhau, trong ví dụ này, tôi sẽ sử dụng giới các bạn cách tạo ConnectionFactory sử dụng giao thức AMQP và TCP.
    • remoteURI sử dụng AMQP: amqp://localhost:5672
    • remoteURI sử dụng TCP: tcp://localhost:61616
  • Tạo Connection từ ConnectionFactory, cần cung cấp username và password.
  • Tạo Session: mỗi Connection có thể có nhiều Session quản lý những thứ như Transaction và lưu giữ Message riêng biệt.
  • Tạo Destination: là một địa chỉ của một Topic hoặc Queue cụ thể được lưu trữ bởi JMS broker.
  • Tạo Producer: producer dành riêng cho một Destination, nó chỉ có thể gửi tin nhắn đến một Topic hoặc Queue cụ thể.
  • Tạo Message: Mỗi khi muốn gửi tin nhắn đến Topic hoặc Queue, cần phải tạo một đối tượng Message. Có một vài loại khác nhau: text, binary, object, IO stream. Trong ví dụ này, tôi chỉ gửi một tin nhắn dạng text, đây là một trong những dạng đơn giản nhất.
  • Gửi Message: thực hiện gửi message đến JMS Broker.
  • Đóng kết nối: sau khi sử dụng xong cần đóng kết nối. Điều này nói với JMS broker rằng nó có thể giải phóng các tài nguyên được sử dụng cho kết nối đó.

Ví dụ:

package com.gpcoder; import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.qpid.jms.JmsConnectionFactory; import javax.jms.*; import java.io.BufferedReader; import java.io.InputStreamReader; class Producer {     public static void main(String[] args) throws Exception {         System.out.println("Create a ConnectionFactory");         // ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");         ConnectionFactory connectionFactory = new JmsConnectionFactory("amqp://localhost:5672");         System.out.println("Create a Connection");         Connection connection = connectionFactory.createConnection("admin", "admin");         connection.start();         System.out.println("Create a Session");         Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);         System.out.println("Create a Topic/ Queue based on the given parameter");         Destination destination = null;         if (args.length > 0 && args[0].equalsIgnoreCase("QUEUE")) {             destination = session.createQueue("gpcoder-jms-queue");         } else if (args.length > 0 && args[0].equalsIgnoreCase("TOPIC")) {             destination = session.createTopic("gpcoder-jms-topic");         } else {             System.out.println("Error: You must specify Queue or Topic");             connection.close();             System.exit(1);         }         System.out.println("Create a Producer to send messages to one Topic or Queue.");         MessageProducer producer = session.createProducer(destination);         System.out.println("Start sending messages ... ");         try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in));) {             String response;             do {                 System.out.print("Enter message: ");                 response = br.readLine().trim();                 TextMessage msg = session.createTextMessage(response);                 producer.send(msg);             } while (!response.equalsIgnoreCase("close"));         }         System.out.println("Shutdown JMS connection and free resources");         connection.close();         System.exit(1);     } }

Tạo Consumer

Các bước thực hiện tương tự như tạo Producer, khác biệt duy nhất là thay vì tạo Producer để gửi tin nhắn, ta tạo Consumer để nhận tin nhắn.

package com.gpcoder; import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.qpid.jms.JmsConnectionFactory; import javax.jms.Connection; import javax.jms.Session; import javax.jms.Destination; import javax.jms.MessageConsumer; import javax.jms.TextMessage; import javax.jms.*; class Consumer {     public static void main(String[] args) throws JMSException {         System.out.println("Create a ConnectionFactory");         // ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");         ConnectionFactory connectionFactory = new JmsConnectionFactory("amqp://localhost:5672");         System.out.println("Create a Connection");         Connection connection = connectionFactory.createConnection("admin", "admin");         connection.start();         System.out.println("Create a Session");         Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);         System.out.println("Create a Topic/ Queue based on the given parameter");         Destination destination = null;         if (args.length > 0 && args[0].equalsIgnoreCase("QUEUE")) {             destination = session.createQueue("gpcoder-jms-queue");         } else if (args.length > 0 && args[0].equalsIgnoreCase("TOPIC")) {             destination = session.createTopic("gpcoder-jms-topic");         } else {             System.out.println("Error: You must specify Queue or Topic");             connection.close();             System.exit(1);         }         System.out.println("Create a Consumer to receive messages from one Topic or Queue.");         MessageConsumer consumer = session.createConsumer(destination);         System.out.println("Start receiving messages ... ");         String body;         do {             Message msg = consumer.receive();             body = ((TextMessage) msg).getText();             System.out.println("Received = " + body);         } while (!body.equalsIgnoreCase("close"));         System.out.println("Shutdown JMS connection and free resources");         connection.close();         System.exit(1);     } }

Chạy ứng dụng

Trước hết, chúng ta cần package ứng dụng trên thành gói jar, chạy lệnh: mvn clean install

Sau khi chạy lệnh trên, trong thư mục target của project, chúng ta có gói: activemq-example-1.0-SNAPSHOT.jar

Start ActiveMQ Server: xem lại bài viết trước “Cài đặt ActiveMQ“.

Trường hợp JMS Queue

Kết nối JMS Client với ActiveMQ

Mô hình P2P (Point to Point) đảm bảo chỉ có một người gửi và một người nhận tin nhắn.

Nhiều Consumer và một Producer

Mở 2 console và chạy lệnh sau để start 2 JMS Consumer:

java -cp target/activemq-example-1.0-SNAPSHOT.jar com.gpcoder.Consumer Queue

Mở thêm 1 console khác để start JMS Producer:

java -cp target/activemq-example-1.0-SNAPSHOT.jar com.gpcoder.Producer Queue

Chúng ta có kết quả như sau:

Kết nối JMS Client với ActiveMQ

Nhập một vài giá trị ở cửa sổ Producer, chúng ta có kết quả sau:

Kết nối JMS Client với ActiveMQ

Như bạn thấy, một tin nhắn chỉ được gửi cho một client tại một thời điểm và client thay phiên nhau nhận tin nhắn.

Hãy đóng các console trên bằng cách enter “exit” trên console của Producer hoặc Ctrl + C.

Producer gửi message trước khi Consumer start

Tiếp tục hãy test thử một trường hợp khác: Start Producer và gửi một vài message:

Kết nối JMS Client với ActiveMQ

Sau đó start Consumer và check kết quả.

Kết nối JMS Client với ActiveMQ

Bạn có thể thấy rằng, người nhận không cần active tại thời điểm Producer gửi message. JMS Broker sẽ deliver message ngay khi Consumer active.

Trường hợp JMS Topic

Kết nối JMS Client với ActiveMQ

Mô hình Pub/ Sub (Publisher/ Subscriber) cho phép 1 người gửi và nhiều người nhận.

Mở 2 console và chạy lệnh sau để start 2 JMS Consumer:

java -cp target/activemq-example-1.0-SNAPSHOT.jar com.gpcoder.Consumer Topic

Mở thêm 1 console khác để start JMS Producer:

java -cp target/activemq-example-1.0-SNAPSHOT.jar com.gpcoder.Producer Topic

Chúng ta có kết quả như sau:

Kết nối JMS Client với ActiveMQ

Nhập một vài giá trị ở cửa sổ Producer, chúng ta có kết quả sau:

Kết nối JMS Client với ActiveMQ

Như bạn thấy, mỗi khi Producer gửi một tin nhắn thì tất cả consumer đều nhận được ngay tức thì. Khi bạn nhập “close” thì chương trình cũng kết thúc và đóng connection.

Hãy đóng các console trên bằng cách enter “exit” trên console của Producer hoặc Ctrl + C.

Tiếp tục hãy test thử một trường hợp khác: start Producer và gửi một vài message. Sau đó start Consumer. Bạn sẽ thấy rằng, Consumer không nhận được message của Producer đã gửi từ trước. Mỗi Consumer sẽ chỉ nhận được message từ Topic sau khi đã subscription.

Mở admin page của ActiveMQ để kiểm tra lại Topic và Queue đã tạo: http://localhost:8161/admin/

Trang Queues:

Kết nối JMS Client với ActiveMQ

Trang Topics:

Kết nối JMS Client với ActiveMQ

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 IT hấp dẫn trên TopDev

Sự khác nhau giữa file application với bootstrap trong Spring

spring boot
Sự khác nhau giữa file application với bootstrap trong Spring

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

Sự khác nhau giữa file application với bootstrap trong Spring

Phân biệt sự khác nhau giữa 2 file cấu hình là application.properties với bootstrap.properties hoặc application.yml với bootstrap.yml.
Khi nào thì sử dụng file cấu hình application, khi nào thì sử dụng file cấu hình bootstrap?

1. File application.properties / application.yml dùng để làm gì?

File application.properties hoặc application.yml được dùng để cấu hình application context (ngữ cảnh ứng dụng)

Khi ứng dụng Spring Boot được khởi động, nó sẽ tạo một application context mà không cần phải chỉ định 1 cách rõ ràng (tự động cấu hình). Đó là nguyên nhân vì sao khi sử dụng spring boot bạn phải cấu hình rất ít.

  Bảo mật ứng dụng Java web bởi Spring Security
  Cách sử dụng properties trong tập tin cấu hình của Spring

Xem thêm nhiều việc làm Spring lương cao trên TopDev

Ngoài việc sử dụng file application.properties hoặc application.yml thì spring cũng cho phép ghi đè lại các cấu hình bằng nhiều cách như sử dụng code, các biến môi trường…

Chúng ta có thể nhóm các thuộc tính cấu hình mà có thể ghi đè trong application context như sau:

  • Core properties (logging properties, thread properties)
  • Integration properties (RabbitMQ properties, ActiveMQ properties)
  • Web properties (HTTP properties, MVC properties)
  • Security properties (LDAP properties, OAuth2 properties)

* Lưu ý: nếu các cấu hình của application context được ghi đè ở nhiều nơi thì cấu hình trong file application.properties hoặc application.yml có ưu tiên thấp hơn

2. File bootstrap.properties / bootstrap.yml dùng để làm gì?

File bootstrap.properties hoặc bootstrap.yml chỉ cần khi sử dụng Spring Cloud.

File bootstrap.properties hoặc bootstrap.yml được dùng để cấu hình bootstrap context. Bootstrap context chính là response của việc load các cấu hình từ một nguồn bên ngoài.

File bootstrap.properties hoặc bootstrap.yml thường gồm 2 thuộc tính:

  • Uri của config server (server chứa các cấu hình): spring.cloud.config.uri
  • Tên của ứng dụng: spring.application.name

Khi ứng dụng Spring Cloud được khởi động, nó sẽ tạo một bootstrap context. Dựa vào các thông tin cấu hình trong file bootstrap.properties hoặc bootstrap.yml, ứng dụng sẽ tạo một http request tới config server với name của ứng dụng để lấy về các thông tin cấu hình tương ứng.

File bootstrap sẽ được ứng dụng nạp vào trước file application.

3. Kết luận

File application.properties hoặc application.yml là nơi chứa cấu hình mặc định của ứng dụng. Còn file bootstrap.properties hoặc bootstrap.yml chỉ dùng cho các ựng dụng spring cloud.

Okay, Done!

References:

https://cloud.spring.io/spring-cloud-commons/multi/multi__spring_cloud_context_application_context_services.html

https://stackoverflow.com/questions/32997352/what-is-the-difference-between-putting-a-property-on-application-yml-or-bootstra

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 IT hấp dẫn trên TopDev

Biết gì về prototype trong Javascript?

prototype trong javascript
Biết gì về prototype trong Javascript?

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

1. OOP trong Javascript

Javascript là một ngôn ngữ dựa trên nguyên mẫu (prototype-based language), nó có nghĩa rằng thuộc tính và phương thức của object có thể được chia sẻ thông qua các đối tượng tổng quát (generalized objects) có khả năng mở rộng.

Trong số các ngôn ngữ hướng đối tượng phổ biến như Java, Python, PHP, Javascript khá là đặc biệt.  JS không hề có class, vậy các tính chất của OOP trên javascript được thể hiện như thế nào?.

Trong bài viết này, ta sẽ tìm hiểu cách thức làm việc của prototype (được hiểu như là kế thừa (inheritance) ở javascript).

  Nếu vỗ ngực xưng tên là một javascript developer sành sỏi, mà không giải thích được prototype inheritance thì thật là kỳ
  Protocol-oriented programming: Trái tim của Swift!

Xem thêm các việc làm JavaScript lương cao trên TopDev

2. Prototype là gì?

(Đối với một số bạn chưa có khái niệm sơ qua về prototype có thể đọc ở bài viết này).

Prototype là cơ chế mà các object trong javascript kế thừa các tính năng từ một object khác.

Prototype

Mỗi một object trong javascript đều có một thuộc tính nội bộ (internal property) gọi là [[Prototype]].

Chúng ta có thể chứng minh điều này bằng cách tạo ra một object mới.

let a = {};

Đây là cách đơn giản nhất để khởi tạo một object, hoặc một cách khác là khởi tạo object với constructor.

let x = new Object().

Dấu ngoặc kép nói lên rằng thuộc tính này không thể truy cập trực tiếp ở code của chúng ta. Để thực hiện việc truy cập, ta sử dụng phương thức getPrototypeOf()

Object.getPrototypeOf(x);

Output ở đây là:

{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, …}

3. Thêm thuộc tính prototype cho các đối tượng

Chúng ta sẽ cùng tìm hiểu sâu hơn với ví dụ sau đây:

function Human(firstName, lastName) {
this.firstName = firstName,
this.lastName = lastName,
this.fullName = function() {
return this.firstName + " " + this.lastName;
}
}

Hãy khởi tạo 2 object person1 và persion2, sử dụng human constructor như sau:

var person1 = new Human("Kien", "Nguyen");
var person2 = new Human("Khai", "Nguyen");

Đầu tiên, khi hàm Human được khởi tạo, javascript sẽ thêm thuộc tính prototype vào hàm. Nói cho dễ hiểu là thằng human sẽ gửi cho constructor 1 cái yêu cầu, nó nói là constructor mày hãy cho tao cái thể hiện đi, constructor hì hục làm việc và trả lại cho nó một cái thể hiện (instance).

javascript-prototype-constructor

Khi ta khởi tạo thêm object human1 bằng hàm constructor:

javascript-prototype-property

Lúc đối tượng này khởi tạo cũng là lúc javascript enginesthêm thuộc tính proto (cũng được gọi là dunder proto) vào đối tượng. Chính dunter proto này sẽ trỏ tới prototype object của hàm constructor.

4. Javascript engines tìm kiếm prototype property như thế nào?

Ta cùng xem xét ví dụ sau đây:

// Tạo một hàm constructor function rỗng 
function Person() {}
// Thêm thuộc tính name, age cho prototype property của hàm Person constructor 
Person.prototype.name = "Kien";
Person.prototype.age = 24;
Person.prototype.sayName = function() {
console.log(this.name);
}
// Khởi tạo object sử dụng hàm khởi tạo của Person 
var person1 = new Person();
// Truy cập tới thuộc tính name sử dụng đối tượng person 
console.log(person1.name) 
// Output Kien

Khi chúng ta cố gắng truy cập thuộc tính của một đối tượng (ở đây là person1.name), việc đầu tiên javascript engines làm là sẽ cố gắng tìm thuộc tính chúng ta cần trên đối tượng, nếu thuộc tính ** tồn tại** trên đối tượng, như thế thì quá đơn giản, chúng ta chỉ việc xuất ra kết quả.

javascript-engines

Nếu không, lúc này nó sẽ kiểm tra thuộc tính ở đối tượng nguyên mẫu (prototype object) hoặc đối tượng mà nó kế thừa. Trường hợp tệ nhất, đến cuối cùng vẫn không tìm được thuộc tính -> kết quả trả về sẽ là undefined.

Đối với ví dụ trên, khi person1.name được gọi, javascript engines sẽ kiểm tra property này có tồn tại trên đối tượng person hay không?. Không may thay, y thuộc tính name không tồn tại trên đối tượng person. Tiếp tục tìm kiếm trên dunder proto hoặc trên prototype của đối tượng person. Rất may thuộc tính name tồn tại trên prototype của đối tượng person. Kết quả là Kien

javascript-prototype-output

Qua hai ví dụ nhỏ này, mong các bạn có một chút hình dùng về cách thức hoạt động của prototype trong javascript.

Sau prototype sẽ là gì?. Sau prototype thì nên tìm hiểu tiếp về closure.

Again, thanks for reading, love u so much!

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

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

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

Sử dụng React-Query để fetch data

react query
Sử dụng React-Query để fetch data

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

React-query sẽ giúp chúng ta giải quyết các vấn đề sau

  • Một global context để lưu trữ dữ liệu lấy về từ server
  • Thiết đặt Caching đơn giản
  3 bước tối ưu hiệu năng React App bằng các API mới của React
  3 tools giúp bạn tăng hiệu năng của React App một cách bất ngờ

Xem thêm chương trình tuyển dụng React hấp dẫn trên TopDev

Nếu thích bạn cũng có thể tham khảo thêm swr cũng khá cool

Chúng ta sẽ có các Server side APIs sau

// api/product.js

// 1. Fetch tất cả products
const useFetchProducts = () => {}

// 2. Fetch một product cụ thể
const useFetchProduct = (id) => {}

// 3. Thêm một product
const useAddProduct = (product) => {}

// 4. Cập nhập một product
const useEditProduct = (product) => {}

// 5. Xóa một product
const useDeleteProduct = (id) => {}

Thực hiện fetch với useQuery

import { useQuery } from 'react-query'

const useFetchProducts = () => {
	return useQuery(
		// định danh
		'products',		() => {
			fetch('/api/products')
		}
	)
}

Sử dụng trong component

import { useFetchProducts } from "../api/products"

const Products = () => {
	const {
		data: products,
		isLoading
	} = useFetchProducts();

	return (
		<div>
			{
				isLoading && <div>Loading...</div>
			}
			{
				products && (
					products.map((product) => {
						<div key={product.id}>
							{product.name}
						</div>
					})
				)
			}
		</div>
	)
}

Việc fetch dữ liệu sẽ còn thêm các tính năng như search, phân trang, filter. Có react-query mọi thứ sẽ vô cùng đơn giản

import { useState } from "react"
import { useFetchProducts } from "../api/products"

const Products = () => {
	// trang hiện tại
	const [page, setPage] = useState(1)
	// số item trên trang
	const [limit, setLimit] = useState(10)
	// từ khóa
	const [name, setName] = useState('')		
	const {
		data: products,
		isLoading
	} = useFetchProducts({
		page,		limit,		name	});

	return (
		<div>
			{
				isLoading && <div>Loading...</div>
			}
			{
				products && (
					products.map((product) => {
						<div key={product.id}>
							{product.name}
						</div>
					})
				)
			}
		</div>
	)
}

Chúng ta cần cập nhập lại useFetchProducts

import { useQuery } from 'react-query'

const useFetchProducts = ({ page, limit, name }) => {
	return useQuery(
		['products', { page, limit, name }],		() => {
			fetch(`/api/products?page=${page}&limit=${limit}&search=${name}`)		}
	)
}

Thực hiện cache

Ví dụ chúng ta muốn đặt cache 10s, chúng ta sẽ sử dụng thiết đặt staleTime

import { useQuery } from 'react-query'

const useFetchProducts = ({ page, limit, name }) => {
	return useQuery(
		['products', { page, limit, name }],
		() => {
			fetch(`/api/products?page=${page}&limit=${limit}&search=${name}`)
		},
		{
			staleTime: 10000		}
	)
}

Cực kỳ đơn giản đúng không!

Tưởng tượng chúng ta có danh sách product hiển thị trên màn hình, click vào một product chúng ta hiển thị pop-up với các thông tin của product

Để fetch một product, chúng ta cũng đồng thời áp dụng cache

const useFetchProduct = (id) => {
	return useQuery(
		['product', id],
		() => {
			fetch(`/api/products/${id}`)
		},
		{
			staleTime: 10000
		}
	)
}

Đến phần thú vị nè, nếu các thông tin của từng product hoàn toán giống với thông tin trả về từ danh sách product?, chúng ta có thể áp dụng cache cho từng product trong lúc fetch danh sách product

import { useQuery, useQueryClient } from 'react-query'

const useFetchProducts = ({ page, limit, name }) => {
	const queryClient = useQueryClient();
	return useQuery(
		['products', { page, limit, name }],
		() => {
			fetch(`/api/products?page=${page}&limit=${limit}&search=${name}`)
		},
		{			
			staleTime: 10000,
			onSuccess: (products) => {				products.forEach(product => {
					queryClient.setQueryData(						['product', product.id],
						product
					);
				})
			}
		}
	)
}

Bằng cách dùng useQueryClient().setQuery, chúng ta force cache cho từng product.id, để khi useFetchProduct chạy nó sẽ có sẵn giá trị cache này và không cần thực hiện gọi API

Thể hiện chút tình yêu với dự án react-query nhé các bạn, star ngay không nói nhiều

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

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

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

Tìm hiểu ngành an ninh mạng: Mức lương và cơ hội nghề nghiệp

ngành an ninh mạng
Ngành An Ninh Mạng Và Những Vấn Đề Liên Quan

Đi cùng với sự phát triển thần tốc của công nghệ và trí tuệ nhân tạo, việc bảo mật thông tin trước các tội phạm công nghệ cao luôn là vấn đề nhức nhối hiện nay. Không khó để bắt gặp các nguồn tin về việc dữ liệu đánh cắp, kể cả là với những công ty có quy mô và thâm niên hoạt động lâu năm. Đó là lý do nhân lực trong ngành an ninh mạng đang ngày càng được săn đón và có nhu cầu tuyển dụng rất cao. Vậy ngành an ninh mạng hiện nay đang phát triển ra sao, cần học gì để làm việc trong ngành này và mức lương hiện của ngành như thế nào? Cùng TopDev tìm hiểu thêm với bài viết dưới đây.

ngành an ninh mạng
Ngành An ninh mạng và những điều cần biết

1. Ngành an ninh mạng là gì?

Ngành an ninh mạng hay còn gọi là Cybersecurity được biết đến là công việc hoạt động nhằm phát hiện, ngăn chặn và ứng phó với các cuộc tấn công đến cổng thông tin mạng và máy tính nhằm mục đích trộm cắp các thông tin mang tính bảo mật. Để làm được việc này, các chuyên gia trong lĩnh vực an ninh mạng sẽ chịu trách nhiệm chính để tạo ra “hàng rào bảo vệ” để ngăn chặn việc tấn công ở các bên trong và bên ngoài hệ thống.

An ninh mạng được đánh giá là ngành nghề hấp dẫn hiện nay trong lĩnh vực công nghệ thông tin. Theo chia sẻ của anh Trần Minh Quảng với TopDev TV, vì ngành Cybersecurity là ngành mới nên khi làm việc bạn sẽ có cơ hội nghiên cứu chuyên sâu và phát triển kỹ năng chuyên môn cho bản thân rất tốt.

Bên cạnh đó, cơ hội việc làm đầy hấp dẫn cùng là động lực để bạn theo đuổi ngành an ninh mạng. Tại Việt Nam, Cybersecurity được đánh giá là một lĩnh vực đang phát triển mạnh và có đội ngũ nhân lực là những chuyên gia hàng đầu, nhờ đó, bạn có cơ hội tiếp xúc và cọ sát với những người giỏi nhiều hơn.

2. Ngành an ninh mạng cần học gì để làm tốt công việc?

2.1. Ngành an ninh mạng thi đầu vào khối nào?

Ngành an ninh mạng hiện nay được tuyển sinh với các khối thi gồm:

  • Khối A: Toán – Lí – Hóa
  • Khối A1: Toán – Lí – Anh
  • Khối D: Toán – Văn – Anh
  • Khối D90: Toán – Anh – KHTN

Điểm chuẩn của ngành an toàn thông tin nói riêng và công nghệ thông tin nói chung hiện nay đang nằm ở mức khá cao. Trong vòng 2 năm trở lại đây, ngành an toàn thông tin của các trường top đầu điểm chuẩn đều trên 20 điểm. Do những cơ hội việc làm và mức lương hấp dẫn mà nhu cầu nộp hồ sơ vào các ngành này đều tăng cao qua mỗi năm.

Xem thêm Cybersecurity: Khám phá những sự thật bất ngờ về ngành an ninh mạng tại Việt Nam

2.2. Ngành an ninh mạng đào tạo những gì?

Trọng tâm kiến thức và đào tạo chuyên môn trong các trường tập trung vào vấn đề bảo vệ dữ liệu cũng như cách phản ứng với các trường hợp tấn công mạng. Một số kiến thức nền tảng sinh viên có thể học như:

  • Quản trị mạng
  • Quản trị thông tin
  • Quản trị hệ thống
  • Mạng lưới thông tin
  • Phân tích dữ liệu
  • Mật mã học đại cương
  • Phòng thủ không gian mạng
  • Hệ thống công nghệ thông tin
  • Nguyên tắc thiết kế bảo mật

Tuy nhiên, phương hướng đào tạo có thể khác nhau giữa các trường. Một số trường tập trung chủ yếu vào lập trình, trong khi các trường khác có thể chuyên sâu vào nghiên cứu pháp y kỹ thuật số (digital forensics) hoặc chính sách an ninh mạng.

Chương trình giảng dạy là yếu tố rất quan trọng khi lựa chọn một chương trình đào tạo an ninh mạng. Giáo án thường bao gồm cả lý thuyết và thực hành, như lập trình máy tính và các kỹ năng thực tế, điều này rất hữu ích cho sự nghiệp sau này của học viên trong lĩnh vực công nghệ thông tin.

Xem thêm các chương trình tuyển dụng Security Engineer trên TopDev

3. Cơ hội việc làm của ngành An ninh mạng

Cơ hội việc làm của ngành An ninh mạng

Làm việc từ xa, Internet of Things (IoT), và sự chuyển dịch ngày càng nhiều khía cạnh của cuộc sống vào không gian kỹ thuật số (cũng như siêu dữ liệu) đã làm gia tăng sự phức tạp của các cuộc tấn công mạng. Điều này tạo ra những thách thức lớn đối với sự an toàn thông tin. Các chuyên gia an ninh mạng hiện đang sử dụng trí tuệ nhân tạo (AI) để dự đoán và ngăn chặn các cuộc tấn công như hack và DDOS. Đồng thời, họ cũng áp dụng các phương pháp tiếp cận tâm lý để đối phó với các kỹ thuật xã hội sử dụng công nghệ thấp hơn. Sự kết hợp của các kỹ năng này làm cho các chuyên gia an ninh mạng trở thành những ứng viên hấp dẫn và phù hợp với lực lượng lao động trong tương lai.

Ngành An ninh mạng đang mở ra nhiều cơ hội nghề nghiệp hấp dẫn và phát triển bền vững. Các tổ chức hiện đang tìm kiếm những chuyên gia có kỹ năng và kiến thức sâu rộng về bảo mật mạng, phòng chống tấn công mạng, phân tích rủi ro và quản lý an ninh thông tin.

Theo thống kê từ Cục An toàn thông tin (Bộ Thông tin và Truyền thông), hiện có khoảng 50.000 người làm việc trong lĩnh vực an toàn thông tin, trong khi nhu cầu nhân lực dự kiến sẽ cần đến khoảng 700.000 người. Điều này cho thấy tiềm năng nghề nghiệp rộng lớn và triển vọng phát triển lâu dài cho những ai theo đuổi ngành An ninh mạng.

4. Mức lương của ngành An ninh mạng

Theo số liệu trong Báo cáo thị trường IT Việt Nam 2023 do TopDev thực hiện, ngành an ninh mạng (Cybersecurity Specialist) hiện đang có mức lương khá cao trong thị trường các việc làm liên quan đến công nghệ thông tin. Mức lương có thể lên đến 3.566 USD với các ứng viên cao cấp. Trong khi đó mức lương của các ứng viên ở cấp độ Basic là 2.072 USD.

Xem thêm Ngành Bảo Mật Thông Tin Và Những Cơ Hội Việc Làm Đầy Hấp Dẫn

Một điều tất yếu đi đôi với mức lương nổi bật hơn hẳn so với mặt bằng chung của thị trường đó là yêu cầu về chất lượng nhân sự đối với ngành an ninh và bảo mật thông tin cũng cao hơn hẳn. Các chuyên viên nhân sự đến từ những công ty hàng đầu luôn gặp rất nhiều khó khăn trong việc tuyển được các ứng viên có năng lực cho những vị trí này.

5. Một số trường chuyên đào tạo ngành An ninh mạng

Việt Nam đang ngày càng chú trọng đến việc đào tạo nhân lực cho lĩnh vực an ninh mạng. Dưới đây là một số trường đại học với chương trình đào tạo chất lượng về an ninh mạng:

Học viện Kỹ thuật Mật mã

Học viện Kỹ thuật Mật mã

Đây là một trường chuyên về đào tạo an toàn thông tin và kỹ thuật mật mã, có kinh nghiệm gần 20 năm về đào tạo ngành An toàn thông tin. Khi theo học tại trường, sinh viên sẽ được đào tạo chuyên nghiệp về các kỹ năng trong lĩnh vực an toàn thông tin, bao gồm việc phân tích và giải mã các thông tin mã hóa, phát hiện và ngăn chặn các cuộc tấn công mạng, thiết kế và triển khai các hệ thống an toàn thông tin,…

Điểm chuẩn ngành An toàn thông tin năm 2023 tại cơ sở Hà Nội là 25.60 và cơ sở TP. Hồ Chí Minh là 25.00.

Đại học Bách Khoa Hà Nội

Đại học Bách Khoa Hà Nội

Ngành An toàn không gian số (Chương trình tiên tiến) là ngành học được thiết kế bởi các giáo sư hàng đầu trong nước và quốc tế. Chương trình được dạy 100% bằng tiếng Anh, với hệ thống các bài thí nghiệm và thực hành theo tiêu chuẩn quốc tế. Sinh viên năm cuối sẽ được hướng dẫn bởi các chuyên gia là cựu sinh viên của trường CNTT&TT đang làm việc tại các công ty tập đoàn lớn như IBM, Bkav, Thales,…

Điểm trúng tuyển của ngành vào năm 2023 là 28.05 điểm với 2 tổ hợp môn xét tuyển là A00 và A01.

Trường Đại học Công nghệ Thông tin (Đại học Quốc gia TP.HCM)

Trường Đại học Công nghệ Thông tin

Ngành An toàn thông tin tại trường Đại học Công nghệ Thông tin được xây dựng theo định hướng chuyên sâu, theo mô hình đào tạo phương Tây, thực hành nhiều giúp sinh viên có kỹ năng tốt và kiến thức chuyên môn cao sau khi tốt nghiệp. Khi học tại trường, sinh viên sẽ được trang bị đầy đủ kiến thức và kỹ năng tương đương với một số chứng chỉ quốc tế như CCNP Security, RHCSS, CCNA,…

Điểm chuẩn xét tuyển của ngành An toàn thông tin năm 2023 là 26.3 điểm với 4 tổ hợp môn A00, A01, D01, D07. Trường áp dụng 3 hình thức tuyển sinh là Tuyển thẳng và ưu tiên xét tuyển, Xét tuyển dựa điểm thi, Xét tuyển dựa trên các chứng chỉ quốc tế uy tín.

Tổng kết

Ngành An ninh mạng sẽ còn tiếp tục phát triển hơn nữa trong tương lai nhờ vai trò đặc biệt quan trọng và cần thiết để bảo mật dữ liệu, thông tin. Hi vọng bài viết này sẽ giúp bạn giải quyết được phần nào thắc mắc liên quan đến ngành An ninh và bảo mật thông tin mạng. Đón xem nhiều bài viết hấp dẫn khác tại TopDev.

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

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

CODEIGNITER bỏ Index.PHP trên URL. Đảm bảo .HTACCESS và MOD_REWRITE đã hoạt động?

codeigniter
CODEIGNITER BỎ INDEX.PHP TRÊN URL. ĐẢM BẢO .HTACCESS VÀ MOD_REWRITE ĐÃ HOẠT ĐỘNG?

Bài viết được sự cho phép của BQT Kinh nghiệm lập trình

Khi deploy project lên server, chắc hẳn không ít bạn đã từng gặp lỗi không nhận diện được index.php 1 cách tự động như dưới localhost.

Trong bài viết này, mình sẽ chia sẻ cách fix lỗi này một cách đầy đủ.

Trước hết chúng ta cần kiểm tra các vấn đề sau:

  • Kiểm tra xem .htaccess có hoạt động không?
  • Kiểm tra xem mod_rewrite có hoạt động không?
  • Thực hiện update cấu hình
  "Code dễ đọc" là như thế nào?
  "Làm PM, theo anh không cần biết về code, nhưng phải hiểu về SQL, database, những khái niệm cơ bản của code"

Kiểm tra .htaccess có hoạt động không?

Cách đơn giản nhất để kiểm tra điều này, bạn mở file .htaccess lên. Thêm bất kì đoạn code nào vào đầu file. VD: <test>. Sau đó khởi động lại Apache. Theo dõi trình duyệt nếu nhận được lỗi như sau thì .htaccess của bạn đã hoạt động bình thường:

Nếu bạn không thấy ‘Interal Server Error’, Apache của bạn đã bỏ qua tệp .htaccess và bạn cần khắc phục điều đó. Nói chung, Apache bỏ qua tệp .htaccess vì cấu hình mặc định đang là AllowOverride none . Kiểm tra cấu hình máy chủ ảo của bạn và thêm / sửa đổi thành AllowOverride All.

Tìm và fix file: /etc/apache2/apache2.conf

Ví dụ:

<Directory /var/www/site/example.com/>
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

Kiểm tra mod_rewrite có hoạt động không?

Các bạn thực hiện theo hướng dẫn ở link sau đây để bật mod_rewrite nhé.

https://stackoverflow.com/questions/869092/how-to-enable-mod-rewrite-for-apache-2-2

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

Cuối cùng, update file .htaccess!

Bước 1: Cập nhật file .htaccess của bạn như sau:

Bước 2: Xóa index.php trong file config.php

$config[‘index_page’] = ”;

Bước 3:

Sửa:

$config['uri_protocol'] ="AUTO"

Thành:

$config['uri_protocol'] ="REQUEST_URI"

Bước 4: Khởi động lại Apache. Và tận hưởng kết quả!

Mọi người có thắc mắc gì để lại comment bên dưới bài viết nhé.

Thấy hữu ích thì chia sẻ cho bạn bè nhé. Mình cảm ơn.

Kinhnghiemlaptrinh.com

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

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

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

TNEX là gì? Sử dụng ứng dụng Tnex có an toàn không?

TNEX là gì
TNEX là gì? Sử dụng ứng dụng Tnex có an toàn không?

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

I. Tnex là gì?

TNEX là một nền tảng Ngân hàng thuần số đầu tiên tại Việt Nam (dành cho cả người dùng phổ thông và chủ cửa hàng).

Tnex được bảo trợ bởi Ngân hàng Hàng Hải Việt Nam (MSB), nó sẽ cung cấp cho bạn những trải nghiệm cực kỳ ấn tượng với TNEX App và TNEX Merchant App.

TNEX hiện đang cung cấp cho chúng ta khá nhiều dịch vụ, dưới đây là các dịch vụ tiêu biểu mà hầu hết người dùng sẽ cần đến:

  • Chuyển tiền nhanh.
  • Thanh toán (hóa đơn điện, nước, viễn thông…)
  • Nạp tiền vào tài khoản thanh toán.
  • Hỗ trợ mở và quản lý tài khoản thanh toán ngay trên ứng dụng TNEX.
  • Quản lý chi tiêu..
  • Đăng kí, quản lý tài khoản thanh toán và thẻ ghi nợ nội địa ngay trên ứng dụng….
  • Có cộng đồng dành riêng cho những người dùng TNEX, bạn có thể dễ dàng tương tác với những người dùng Tnex khác…

Ngoài ra, bạn có thể tham khảo thêm thông tin về TNEX thông qua video bên dưới này nhé.

II. Sử dụng Tnex có an toàn không?

Như mình đã trình bày với các bạn ở trên rồi đó, Tnex được bảo trợ bởi ngân hàng MSB. Vậy nên bạn hoàn toàn yên tâm khi sử dụng dịch vụ này nhé !

  AB testing là gì? Tại sao phải làm AB testing?

III. Hai tính năng khác biệt tiêu biểu của Tnex

#1. Miễn hoàn toàn các loại phí

Hầu hết các ngân hàng truyền thống đều sẽ thu các khoản phí phát sinh như phí chuyển khoản, phí rút tiền mặt bằng thẻ tại ATM hoặc tại quầy, các phí thường niên như là phí quản lý tài khoản, phí quản lý thẻ, phí báo biến động số dư SMS, phí ngân hàng điện tử, …

Thậm chí, một số ngân hàng còn yêu cầu bạn duy trì số dư tối thiểu trong tài khoản (gọi là tiền duy trì tài khoản) và tất nhiên là bạn không thể rút số tiền này được.

Nếu xét từng loại phí thì có thể bạn sẽ thấy nó không đáng là bao, nhưng nếu tính tất cả trong một năm và cộng dồn lại thì chúng ta cũng tiết kiệm được một số tiền kha khá đấy.

cach-su-dung-ung-dung-tnex (1)Ưu điểm vượt trội của Tnex (bên trái) so với nhiều ngân hàng truyền thống (bên phải)

#2. Tạo tài khoản và thẻ nhanh chóng, không cần ra phòng giao dịch

Đối với ngân hàng truyền thống, khi đăng kí tài khoản hoặc phát hành thẻ thì bạn cần phải đích thân ra phòng giao dịch để hoàn thành các thủ tục cần thiết.

Còn đối với TNEX thì bạn chỉ cần bỏ ra vài phút đăng kí trên smartphone là đã có ngay tài khoản và thẻ chỉ với vài thao tác đơn giản, an toàn và cực kỳ bảo mật rồi.

TNEX làm được như vậy là nhờ vào việc ứng dụng công nghệ eKYC, một công nghệ bảo mật tuyệt đối. Công nghệ này cho phép nhận dạng và định danh khách hàng hoàn toàn trực tuyến.

KYC (là viết tắt của từ Know Your Customer) – đây là một giải pháp định danh ngân hàng trực tuyến, giúp ngân hàng có thể xác định và xác minh danh tính của khách hàng một cách chính xác. KYC sẽ trở thành tiêu chuẩn trong ngành tài chính, ngân hàng..

Quy trình KYC sẽ là xác minh thẻ ID, nhận dạng và xác minh khuôn mặt, xác minh giấy tờ (như hóa đơn tiền điện, nước nhà bạn, hoặc là thu nhập cá nhân của bạn..) và xác minh sinh trắc học.

Với eKYC thì khác hàng có thể xác thực và định danh 100% online, bạn không cần ra các chi nhánh ngân hàng để làm gì thêm.

cach-su-dung-ung-dung-tnex (2)

Tài khoản ngân hàng là nơi chứa tiền, là nơi chứa “mồ hôi và nước mắt” của bạn nên luôn luôn được TNEX đảm bảo an toàn tuyệt đối bằng các phương thức bảo mật đạt chuẩn Quốc tế. Bạn sẽ nhận được thông báo qua số điện thoại và thư điện tử khi:

  • Số dư trong tài khoản của bạn có sự biến động (tăng lên hoặc giảm đi).
  • Có sự thay đổi thông tin tài khoản như mật khẩu hoặc số điện thoại.
  • Tài khoản của bạn được đăng nhập từ một thiết bị.

Thẻ được phát hành bởi Napas, uy tín và mức độ bảo mật của đơn vị này thì không cần phải bàn đến. Trong trường hợp không may, thẻ bị thất lạc thì bạn cũng có thể chủ động khóa thẻ ngay trên ứng dụng Tnex.

cach-su-dung-ung-dung-tnex (3)

IV. Chỉ một thao tác được 2 sản phẩm

#1. Tài khoản

Ngay khi quá trình phê duyệt hoàn thành bạn sẽ nhận được 2 loại tài khoản, đó là: Tài khoản thanh toán và tài khoản thanh toán Energy:

  • Tài khoản thanh toán được sử dụng để chuyển và nhận tiền, liên kết với thẻ ghi nợ nội địa để thực hiện các giao dịch bằng thẻ tại ATM.
  • Tài khoản thanh toán Energy được sử dụng để thực hiện các giao dịch thanh toán hàng hóa qua QR Code, thanh toán hóa đơn, nạp tiền điện thoại … trên ứng dụng TNEX.

cach-su-dung-ung-dung-tnex (4)

Các bạn nên chú ý:

  • Tiền trong tài khoản thanh toán là tiền thật 100%, được bảo chứng bởi Ngân hàng TMCP Hàng Hải Việt Nam (MSB).
  • Tiền trong tài khoản Energy là tiền ảo, được sử dụng riêng trong hệ sinh thái của TNEX – vì vậy bạn không thể chuyển tiền hoặc rút tiền ra được nhé.
  • Và một điều nữa, bạn có thể chuyển tiền từ tài khoản thanh toán sang tài khoản Energy, nhưng bạn không thể làm điều ngược lại.

#2. Thẻ Tnex vật lý

Thẻ TNEX là thẻ ghi nợ nội địa được phát hành dựa trên tài khoản thanh toán.

Với thẻ ghi nợ nội địa này thì bạn có thể sử dụng để thanh toán trực tuyến, sử dụng thanh toán với phần mềm POS (phần mềm quản lý bán hàng), chuyển tiền, rút tiền mặt tại ATM.

Sự ưu việt của thẻ TNEX

  • Tích hợp công nghệ Contactless cho phép bạn thực hiện thanh toán cực nhanh và đơn giản nhưng vẫn đảm bảo tính bảo mật.
  • Không cần mất thời gian đi đến các cây ATM với ứng dụng TNEX là đã có thể tạo và đổi mã PIN một cách dễ dàng.
  • Sau khi đang kí phát hành thẻ (ngay trong ứng dụng) thẻ sẽ được ship đến “tận giường” của bạn hoàn toàn miễn phí. Mã PIN lần đầu sẽ được ngân hàng gửi tới bạn qua tin nhắn SMS theo số điện thoại bạn đã đăng ký.

V. Các bước đăng kí tài khoản TNEX

#1. Cần chuẩn bị những gì?

  • Smartphone chạy các phiên bản gần đây của hệ điều hành Android hoặc iOS. Bản iOS/ Android cũ quá sẽ không cài đặt được ứng dụng TNEX vì lý do bảo mật.
  • Giấy tờ tùy thân của bạn, ví dụ như: Chứng minh nhân dân, hoặc thẻ căn cước công dân….

#2. Các thực hiện đăng ký tài khoản TNEX

+ Bước 1: Trước tiên bạn cần phải cài đặt ứng dụng TNEX – Ngân hàng số thế hệ mới (đừng nhằm lẫm với TNEX Merchant).

TNEX Merchant cũng là của Tnex, nhưng là dành cho những người kinh doanh online, chủ nhà hàng…. chúng ta là người dùng phổ thông thì dùng TNEX ngân hàng số thôi nhé các bạn !

Bạn có thể truy cập thông qua link bên dưới để không bị cài nhầm nhé:

  • Link dành cho iOS (iPhone, iPad): Tải về !
  • Link dành cho Android (Samsung, OPPO, Xiaomi…..): Tải về !

cach-su-dung-ung-dung-tnex (5)

+ Bước 2: Nhập số điện thoại, mật khẩu truy cập và thư điện tử của bạn vào:

  • Số điện thoại phải là số chính chủ nhé các bạn.
  • Mật khẩu truy cập hợp lệ là mật khẩu có độ dài ít nhất 6 ký tự (bao gồm chữ thường, số, chữ hoa, và ký tự đặc biệt).

cach-su-dung-ung-dung-tnex (6)

+ Bước 3: Chụp mặt trước và mặt sau của chứng minh nhân dân hoặc căn cước công dân… Hay là bất cứ giấy tờ gì mà bạn dùng để xác minh.

cach-su-dung-ung-dung-tnex (7)

+ Bước 4: Chụp ảnh khuôn mặt và thực hiện các thao tác theo đúng hướng dẫn trên ứng dụng (xoay trái, mỉm cười, nhắm mắt, xoay trái).

cach-su-dung-ung-dung-tnex (8)

+ Bước 5: Kiểm tra, bổ sung thông tin đăng ký và xác nhận đồng ý với các điều kiện điều khoản dịch vụ của ngân hàng.

cach-su-dung-ung-dung-tnex (9)

+ Bước 6: Nhập mã OTP được gửi tới số điện thoại mà bạn đã khai báo ở Bước 2 để xác thực.

cach-su-dung-ung-dung-tnex (10)

Đến đây thì quá trình đăng kí đã hoàn thành và tất các thông tin đăng ký của bạn đã được hệ thống của TNEX ghi nhận. Thông thường bạn sẽ có tài khoản ngay sau khi đăng ký.

Nếu không may (rất hiếm khi xảy ra), bạn sẽ rơi vào một trong hai trường hợp bên dưới thì thời gian kiểm duyệt thông tin tài khoản của bạn kéo tối đa là 2 ngày làm việc kể từ thời điểm bạn đăng ký.

  • Ảnh chứng minh nhân dân hoặc căn cước công dân của bạn chụp bị mờ.
  • Bạn đã thay đổi thông tin sau khi TNEX trích xuất thông tin từ Chứng minh nhân dân hoặc Căn cước công dân.

VI. Hạn mức giao dịch của tài khoản thanh toán

  • Hạn mức theo tháng: Tổng giá trị giao dịch qua tài khoản thanh toán mở trực tuyến bằng ứng dụng TNEX là 100 triệu đồng/ tháng/ khách hàng
  • Hạn mức theo ngày và theo từng giao dịch: Bạn có thể tham khảo hình bên dưới nhé.

cach-su-dung-ung-dung-tnex (11)

VII. Một số câu hỏi thường gặp

#1. Có thay đổi được số điện thoại đăng ký Tnex không?

CÓ ! Bạn có thể vào phần Profile => chọn tính năng chỉnh sửa số điện thoại đăng nhập => và thực hiện theo các bước như ứng dụng hướng dẫn.

#2. Có thay đổi được CMTND/ CCCD không?

CÓ ! Bạn cũng vào Profile => chọn tính năng chỉnh sửa thông tin KYC => và thực hiện theo các bước như ứng dụng hướng dẫn.

#3. Sau khi đăng ký Tnex xong, có phải liên kết với tài khoản ngân hàng không?

Bản thân TNEX đã là một ứng dụng ngân hàng rồi, vậy nên nó đã cung cấp cho bạn tài khoản thanh toán của ngân hàng và đầy đủ các dịch vụ ngân hàng đi kèm với tài khoản thanh toán.

Vậy nên bạn không cần phải liên kết với bất kỳ tài khoản ngân hàng nào khác để sử dụng TNEX. Rất hữu ích cho những bạn nào chưa có tài khoản ngân hàng.

#4. Làm thế nào để có được thẻ Tnex vật lý?

Bạn có thể truy cập vào ứng dụng TNEX và yêu cầu phát hành thẻ vật lý. Mã PIN lần đầu sẽ được Tnex gửi tới bạn số điện thoại mà bạn đã dùng để đăng ký.

#5. Câu hỏi khác….

Còn vô số các câu hỏi và câu trả lời khác, nếu bạn muốn tìm hiểu chi tiết hơn thì truy cập vào đây để đọc thêm nhé: https://www.tnex.com.vn/hoi-dap/

VIII. Lời kết

Vâng, như vậy là mình đã vừa giới thiệu và hướng dẫn đến các bạn cách sử dụng ứng dụng Tnex – một ứng dụng ngân hàng số miễn phí 100% các loại phí (với cam kết trọn đời của Tnex).

Vì TNEX là một ứng dụng thuần việc nên cách sử dụng rất đơn giản, mình không hướng dẫn chắc các bạn cũng biết (thật sự rất đơn giản, không tin bạn cứ đăng kí và trải nghiệm thử :D).

Các thao tác sử dụng tương tự như các ứng dụng ngân hàng điện tử VietinBank iPay, VCB Digibank, … hoặc các ví điện tử như Viettelpay, MoMo, ZaloPay, AriPay, …

Xin chào tạm biệt và hẹn gặp lại các bạn trong những bài viết tiếp theo..

CTV: Nhựt Nguyễn – Bài viết gốc tại blogchiasekienthuc.com

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

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