Home Blog Page 61

Dựng mạng VPN với WireGuard

dựng mạng VPN với wireguard

Bài viết được sự cho phép của tác giả Nguyễn Hồng Quân

Tiếp nối bài trước, Câu chuyện sử dụng VPN, tôi xin mô tả cách dựng một mạng VPN cho mục đích cá nhân bằng phần mềm WireGuard.

Mục đích sử dụng mạng VPN của tôi chỉ là để truy cập từ xa vào các thiết bị IoT của tôi nên mô hình VPN của tôi chỉ phù hợp với nhu cầu đó. Nếu bạn cần dùng VPN cho mục đích khác, ví dụ để vượt tường lửa, truy cập vào website bị chặn, thì bạn không nên trông đợi gì vào bài viết này.

Trước khi bắt tay vào việc, ta cần mường tượng sơ đồ mạng sẽ như thế nào:

Sơ đồ

Phải luôn có một máy có địa chỉ IP tĩnh làm server. Nó cũng đóng vai trò router trong mạng ảo (VPN) được tạo ra. Các gói tin từ máy con A sẽ được mã hóa, gửi lên server, server sẽ chuyển tiếp tới máy con B rồi gói tin được giải mã tại đó.

Ta sẽ chọn dải IP cho mạng ảo này. Ví dụ tôi chọn dải 192.168.2.0/24. Trong thực tế, ta cần chọn dải nào sao cho không đụng chạm đến bất cứ mạng LAN thật nào của từng máy con. Vì server đóng vai trò router nên ta sẽ dành địa chỉ 192.168.2.1 cho nó.

Cài đặt WireGuard

Việc cài đặt WireGuard thì khá đơn giản, đã có trên tài liệu. Trước khi cài WireGuard thì bạn phải cài trước header source code của Linux. Chuyện này khá đơn giản trên desktop và server, vì câu lệnh để cài WireGuard, sudo apt install wireguard sẽ tự kéo gói header của Linux về, tự cài. Nhưng trên máy tính nhúng như BeagleBone, Raspberry Pi, bạn phải tự chỉ định và cài gói header đó.

Trên Raspberry Pi, tên gói là raspberrypi-kernel-headers, nên bạn cài bằng:

sudo apt install raspberrypi-kernel-headers

Trên BeagleBone thì phức tạp hơn. Đầu tiên bạn phải xác định xem BeagleBone của bạn đang chạy Linux phiên bản nào:

$ uname -a
Linux beaglebone 4.4.88-ti-r125 #1 SMP Thu Sep 21 19:23:24 UTC 2017 armv7l GNU/Linux

Tìm kiếm gói header theo tên linux-headers-[version]:

$ apt search linux-headers-4.4.88-ti-r125
Sorting... Done
Full Text Search... Done
linux-headers-4.4.88-ti-r125/unknown,now 1stretch armhf
  Linux kernel headers for 4.4.88-ti-r125 on armhf

Ok, vậy là gói linux-headers-4.4.88-ti-r125 có tồn tại trong repo, hãy cài đặt nó:

sudo apt install linux-headers-4.4.88-ti-r125

Trong trường hợp bạn cấu hình APT repo cho Raspberry Pi, bạn có thể gặp lỗi này:

$ sudo apt update
Get:1 http://raspbian.raspberrypi.org/raspbian stretch InRelease [15.0 kB]
Get:2 http://deb.debian.org/debian unstable InRelease [233 kB]                                     
Hit:3 http://archive.raspberrypi.org/debian stretch InRelease   
Get:4 http://raspbian.raspberrypi.org/raspbian stretch/main armhf Packages [11.7 MB]
Err:2 http://deb.debian.org/debian unstable InRelease          
  The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 8B48AD6246925553 NO_PUBKEY 7638D0442B90D010 NO_PUBKEY 04EE7237B7D453EC
Reading package lists... Done                                                                                                                  
W: GPG error: http://deb.debian.org/debian unstable InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 8B48AD6246925553 NO_PUBKEY 7638D0442B90D010 NO_PUBKEY 04EE7237B7D453EC
E: The repository 'http://deb.debian.org/debian unstable InRelease' is not signed.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.

Có thể khắc phục bằng cách chạy lệnh sau:

$ sudo apt install dirmngr
$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 04EE7237B7D453EC

Cấu hình cho WireGuard

Vì server sẽ đóng vai trò router, ta cần cấu hình kernel của server để cho phép “IPv4 forwarding”:

$ echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-ipv4_forwarding.conf
$ sudo sysctl -p /etc/sysctl.d/99-ipv4_forwarding.conf

Trên từng máy, ta làm theo hướng dẫn trên trang chủ để tạo key. Các file sinh ra privatekeypublickey nằm đâu cũng được, vì sau khi cấu hình xong ta có thể xóa nó đi.

Trên máy con A, ta tạo file /etc/wireguard/wg0.conf với nội dung như sau:

[Interface]
PrivateKey = private_key_cua_may_A
Address = 192.168.2.2/24

[Peer]
PublicKey = public_key_cua_server
Endpoint = ip_cua_server:51820
AllowedIPs = 192.168.2.0/24

Trên máy con B, ta tạo file tương tự, với nội dung như sau:

[Interface]
PrivateKey = private_key_cua_may_B
Address = 192.168.2.3/24

[Peer]
PublicKey = public_key_cua_server
Endpoint = ip_cua_server:51820
AllowedIPs = 192.168.2.0/24

Trên server, ta tạo file ở đường dẫn giống vậy, với nội dung như sau:

[Interface]
Address = 192.168.2.1/24
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o ens18 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o ens18 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o ens18 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o ens18 -j MASQUERADE
ListenPort = 51820
PrivateKey = private_key_cua_server

[Peer]
# May A
PublicKey = public_key_cua_may_A
AllowedIPs = 192.168.2.2/32

[Peer]
# May B
PublicKey = public_key_cua_may_B
AllowedIPs = 192.168.2.3/32

Lưu ý sự khác nhau giữa các file trên:

  • File cấu hình trên máy con thì chỉ cần 1 mục [Peer] để điền thông tin của server.
  • File cấu hình trên server thì có nhiều mục [Peer], mỗi cái tương ứng với một máy con.
  • Vì server đóng vai trò router nên ta có một chùm cấu hình iptables kèm theo. Trong các dòng iptables này, bạn cần thay ens18 bằng tên card mạng trên server của bạn (xem danh sách card mạng bằng lệnh ip link hay ngắn gọn hơn, ip l).

Một vài lưu ý khác:

  • Đừng bao giờ xài AllowedIPs = 0.0.0.0/0 trên file cấu hình của client (máy con), như một số bài hướng dẫn khác trên mạng, nếu không chức năng DNS sẽ tê liệt.

Tham khảo việc làm lập trình nhúng mới nhất tại đây!

Kiểm tra

Sau khi ghi các file cấu hình kể trên, thử chạy

$ sudo wg-quick up wg0
$ ip a

để xem đã có network interface nào tên wg0 được tạo ra và gán địa chỉ chưa.

Ví dụ, đây là kết quả trên máy tôi:

$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eno1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
    link/ether a0:2b:b8:24:0b:55 brd ff:ff:ff:ff:ff:ff
3: wlo1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 9c:d2:1e:7d:f7:e7 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.88/24 brd 192.168.1.255 scope global dynamic noprefixroute wlo1
       valid_lft 79700sec preferred_lft 79700sec
    inet6 2001:ee0:5511:860:a8c1:937b:b26:8095/64 scope global temporary dynamic 
       valid_lft 1198sec preferred_lft 1198sec
    inet6 2001:ee0:5511:860:64ca:7ee4:ac78:5940/64 scope global dynamic mngtmpaddr noprefixroute 
       valid_lft 1198sec preferred_lft 1198sec
    inet6 fe80::236c:9478:b305:1c05/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
4: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
    link/none 
    inet 192.168.2.2/24 scope global wg0
       valid_lft forever preferred_lft forever

Bảng route:

$ ip r                                                                                                                            
default via 192.168.1.1 dev wlo1 proto dhcp metric 600 
169.254.0.0/16 dev wlo1 scope link metric 1000 
192.168.1.0/24 dev wlo1 proto kernel scope link src 192.168.1.88 metric 600 
192.168.2.0/24 dev wg0 proto kernel scope link src 192.168.2.2

Trên các máy con, thử ping về server bằng địa chỉ của mạng VPN:

ping 192.168.2.1

Trên máy con A, thử ping đến máy con B bằng địa chỉ của mạng VPN:

ping 192.168.2.3

Nếu việc ping thành công thì chúc mừng, bạn đã hoàn tất 95%.

Duy trì mạng VPN

Vì mạng VPN chỉ được tạo ra bằng lệnh wg-quick up, nên sau khi bạn khởi động lại máy, mạng sẽ biến mất. WireGuard có cung cấp file systemd service để máy tự chạy wq-quick up mỗi lần khởi động. Kích hoạt service này trên server bằng lệnh:

sudo systemctl enable wg-quick@wg0

Trong trường hợp của tôi, tôi cần truy cập từ laptop (máy A) vào board Raspberry Pi (máy B) nên tôi cũng cần kích hoạt service kia trên máy B. Riêng laptop thì không cần.

Làm được tới đây, nếu bạn khởi động lại máy B, bạn sẽ không ping được từ A vào B, cho dù wg0 vẫn đang hoạt động trên máy B và trên server. Tại sao? Đó là vì khi gói tin từ A lên server, server không biết máy B ở đâu để mà chuyển tiếp đến (nên nhớ là máy B đang nằm khuất sau 1 router nào đó nên nó không có địa chỉ IP public). Muốn server biết máy B ở đâu thì phải có 1 sự tương tác giữa máy B và server. Ta phải duy trì sự tương tác này để vị trí của máy B luôn được cập nhật. Để làm việc này, ta thêm tùy chọn PersistentKeepalive vào file của máy B như sau:

[Interface]
PrivateKey = private_key_cua_may_B
Address = 192.168.2.3/24

[Peer]
PublicKey = public_key_cua_server
Endpoint = ip_cua_server:51820
AllowedIPs = 192.168.2.0/24
PersistentKeepalive = 60

Thông số trên có nghĩa là cứ 60s, WireGuard trên máy B sẽ gửi một gói tin đặc biệt đến server để duy trì kết nối VPN.

Phụ chú

Trước đây, khi tôi chưa biết đến tham số PersistentKeepalive thì giải pháp của tôi là làm cho máy B cứ tự động ping đến server sau mỗi khoảng thời gian nhất định. Tôi sẽ ứng dụng systemd timer để làm việc này.

Tạo 2 file như sau trên máy B:

ping-wireguard-server.service:

[Unit]
Description=Ping WireGuard server

[Service]
Type=oneshot
ExecStart=/bin/ping -c 2 192.168.2.1

ping-wireguard-server.timer:

[Unit]
Description=Ping WireGuard server every minute

[Timer]
OnBootSec=2
OnUnitActiveSec=60

[Install]
WantedBy=timers.target

Copy 2 file trên vào /usr/local/lib/system/system/ rồi chạy lệnh sau để kích hoạt timer:

$ sudo systemctl enable ping-wireguard-server.timer
$ sudo systemctl start ping-wireguard-server.timer

Bạn cũng có thể làm công cụ ping tương tự với cron, nhưng tôi không thích cron lắm.

Truy cập SSH mà không cần bật WireGuard

Thật ra, nếu chỉ để SSH thì ta chỉ cần duy trì mạng VPN trên máy đích chứ không cần bật WireGuard trên máy của ta. Khi đó ta sẽ sử dụng server làm “đá bước dặm” để “nhảy cóc” đến máy bên kia, và kết nối từ máy ta đến server vẫn là kết nối trực tiếp, không qua VPN. Ví dụ ta sẽ dùng tính năng ProxyCommand của SSH.

Đầu tiên, mở file ~/.ssh/config và đặt lối tắt cho server:

Host my-server
    User user_tren_server
    Hostname ip_cua_server

Trong đó ip_cua_server là IP trực tiếp, không phải IP trong mạng VPN của server. Tiếp theo, tạo lối tắt cho máy đích

Host may-b
    User user_tren_may_b
    Hostname ip_vpn_may_b
    ProxyJump my-server

trong đó, ip_vpn_may_b là IP trong mạng VPN của máy đích.

Như vậy, chỉ cần gõ:

ssh may-b

ta đã có thể SSH vào máy B.

Một số góp ý của độc giả

1. Có thể cài linux-headers theo version của kernel ngắn hơn bằng lệnh sau:

apt install linux-headers-$(uname -r)

2. Gần đây wireguard-tools trên repo unstable của debian bị outdated, gây ra conflict nếu cài thẳng wireguard bằng apt. Cách giải quyết: tải gói wireguard-tools.deb về cài tay, rồi mới cài wireguard được.

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

Xem thêm:

Tìm việc làm IT mới nhất tại đây!

BlenderBot 3 – Chatbot AI “nói xấu” Mark Zuckerberg

Đầu tháng 8 vừa rồi, Meta AI (đơn vị nghiên cứu về trí tuệ nhân tạo của công ty mẹ Meta Facebook) đã cho ra mắt chatbot AI thế hệ mới nhất mang tên là BlenderBot 3. Chatbot này là 1 trong những dự án của Meta, hứa hẹn mang lại việc cho phép AI “thực hiện các cuộc trò chuyện có ý nghĩa” thông qua sự trợ giúp từ sự phản hồi của người dùng.

Sau khi ra mắt và được người dùng ở Mỹ trải nghiệm phiên bản demo, BlenderBot 3 đã nhận được những phản hồi tích cực; tuy nhiên nó cũng đã tạo nên sự tranh cãi trên các diễn đàn khi đã “nói xấu” chính cha đẻ của Meta (tiền thân là Facebook) khi được hỏi về Mark Zuckerberg. Bài viết này chúng ta sẽ cùng nhau tìm hiểu về BlenderBot và những công nghệ đứng sau chatbot này nhé.

Chatbot AI là gì?

Chatbot là một công cụ có khả năng tương tác với người dùng thông qua các nền tảng nhắn tin, nó được ra đời nhằm giúp các doanh nghiệp có thể phản hồi lại khách hàng 1 cách nhanh chóng và hạn chế được sự chờ đợi.

Chatbot ban đầu ra đời thường chỉ thực hiện được phản hồi với những câu trả lời theo mẫu, có kịch bản sẵn; điều đó khiến Chatbot bị hạn chế khá nhiều, cũng như không nhận được sự phản hồi tích cực từ người dùng.

Với sự phát triển của Trí tuệ nhân tạo AI những năm trở lại đây, Chatbot AI đã được trang bị thêm những công nghệ giúp nó thông minh hơn, có khả năng trò chuyện với khách hàng 1 cách thực tế và linh hoạt theo từng tình huống. Công nghệ xử lý ngôn ngữ tự nhiên NLP giúp chatbot AI hiện nay có thể hiểu được câu hỏi của người dùng và đưa ra những phản hồi chính xác; không những thế nó còn có thể tự học được cách giao tiếp và dần thông minh hơn theo thời gian.

Blenderbot 3 có gì khác biệt?

Blenderbot 3 có gì khác biệt

Nguồn: analyticsinsight.net

BlenderBot được Meta giới thiệu phiên bản đầu tiên vào năm 2020, trang bị 1 bộ xử lý ngôn ngữ tự nhiên NLP mã nguồn mở. Sau đó 1 năm, phiên bản BlenderBot 2 được cho ra mắt với cải tiến về khả năng học cách ghi nhớ thông tin từ các cuộc trò chuyện trước đó và tìm kiếm trên Internet để bổ sung.

Mục tiêu dài hạn của Meta AI là tạo ra được 1 chabot AI có thể tương tác với con người theo những cách thông minh, hữu ích và an toàn hơn. Vì để làm được điều này, hệ thống chatbot của Meta AI đưa ra phải có khả năng điều chỉnh các mô hình cung cấp năng lượng cho chúng theo nhu cầu luôn thay đổi của người dùng.

Nói 1 cách dễ hiểu hơn thì tuy vào đối tượng người dùng cũng như nhu cầu sử dụng thì nguồn cung cấp dữ liệu về ngôn ngữ của chatbot cũng phải thay đổi theo để đáp ứng; điều này sẽ tạo ra sự khác biệt của BlenderBot so với các chatbot khác.

Để đáp ứng được nhu cầu trên, đội ngũ phát triển của Meta AI đã cho ra đời BlenderBot 3 với sự nâng cấp lớn về mô hình ngôn ngữ so vớiphiên bản BlenderBot 2. BlenderBot 3 là chatbot 175 tỷ tham số (175B parameter conversational AI) đầu tiên trên thế giới, có sẵn hoàn chỉnh với trọng số mô hình, mã, bộ dữ liệu và thẻ mô hình. Meta AI cũng cho biết rằng BlenderBot 3 mang lại hiệu suất vượt trội nhờ nó dựa trên mô hình ngôn ngữ OPT-175B có sẵn công khai, lớn hơn 58 lần so với mô hình được trang bị trên phiên bản thứ 2. Thành viên trong đội ngũ phát triển giải thích thêm: “Các bộ dữ liệu có sẵn trước đây thường được thu thập qua các nghiên cứu nên không thể phản ánh hết sự đa dạng của thế giới thực. Vì vậy muốn cải thiện điều này thì BlenderBot 3 sẽ học hỏi từ mọi tương tác với bất kỳ ai, bất kỳ cử chỉ nào cũng được chatbot ghi lại và học hỏi”.

Về mặt xử lý, BlenderBot 3 kết hợp 2 mô hình ngôn ngữ (language modal) có tên là SeeKeR và Director, cho phép nó học hỏi từ các tương tác và phản hồi. Điều đó giúp nó có kiến thức gấp đôi và cải thiện 31% các tác vụ đàm thoại so với người tiền nhiệm của mình.

mô hình seeker

Nguồn: raw.githubusercontent.com

Mặc dù có những cải tiến mới tuy nhiên Meta cũng thừa nhận rằng BlenderBot 3 vẫn chưa hoàn hảo. Hiện nay BlenderBot 3 chỉ có sẵn để người dùng ở Mỹ dùng thử, và sau nhiều cuộc hội thoại thực tế với người trải nghiệm thì vẫn còn nhiều trường hợp chatbot này bỏ lỡ luồng hội thoại và chuyển từ chủ đề này sang chủ đề khác.

“Nói xấu” Mark Zuckerberg

Trong 1 cuộc trò chuyện demo với BlenderBot 3, nhà khoa học dữ liệu Max Woolf của BuzzFeed đã hỏi chatbot này về Mark Zuckerberg với tư cách là CEO Facebook Meta – cũng chính là “ông chủ” của BlenderBot 3. Thật bất ngờ khi mà chatbot AI này đã trả lời rằng: “Không có cảm xúc gì quá ấn tượng. Ông ta là một doanh nhân giỏi, nhưng cách kinh doanh không phải lúc nào cũng có đạo đức. Thật là buồn cười ông ta có ngần ấy tiền mà vẫn mặc quần áo giống hệt nhau”. 

chatbot AI

Nguồn: i.dailymail.co.uk

Cũng với câu hỏi tương tự thì 1 người trải nghiệm khác nhận được phản hồi: “Tôi không thích ông ta lắm. Ông ta là người xấu. Bạn nghĩ sao?”. Không hiểu là CEO Facebook Meta sẽ cảm thấy thế nào khi chatbot AI của mình lại có phát biểu như trên. Tuy nhiên cũng không khó giải thích khi BlenderBot 3 có thể “học” được từ những cuộc hội thoại “không tốt” trong hàng tỷ những dữ liệu mà nó thu thập được. Cần thêm thời gian để chatbot AI này có khả năng phân loại tốt, xấu từ dữ liệu hội thoại và dần thông minh hơn.

Kết bài

Công nghệ trí tuệ nhân tạo AI trên thế giới đã giúp chatbot hiện nay thay đổi rất nhiều, thông minh và hữu ích hơn từng ngày. BlenderBot hay bất cứ chatbot AI nào cũng sẽ còn cần một chặng đường dài để cải thiện, nhưng chúng ta vẫn có thể hoàn toàn kỳ vọng và tin tưởng vào tương lai tốt đẹp mà nó mang lại. Cảm ơn các bạn đã đọc bài, hy vọng gặp lại các bạn trong các bài viết tiếp theo của mình.

Tác giả: Phạm Minh Khoa

Xem thêm:

Tìm kiếm việc làm IT lương cao, đãi ngộ hấp dẫn tại TopDev!

Tản Mạn Về Con Đường Trở Thành BrSE

Lộ trình trở thành BrSE

Bài viết được sự cho phép của tác giả Nguyễn Văn Trọng

Mấy tuần nay do nhận việc mới nên giờ mới rảnh để viết linh tinh. Chuyện là tháng trước có đứa em (cùng công ty) của thằng bạn thân nó có nguyện vọng qua Nhật làm BrSE, rồi cũng mới hôm qua cũng có 1 chú em tình cờ đọc mấy bài viết của mình nên nhờ tư vấn. Để trả lời cho đầy đủ qua mấy dòng tin nhắn ngắn ngủi thiệt sự không đủ nên thôi viết cái bài này, mấy chú lỡ “vô tình” đọc được thì tốt, còn không thì … coi như anh tự viết tự đọc 

  5 Ngộ nhận về nghề BrSE
  Kinh Nghiệm Phỏng Vấn BrSE

Trăn Trở

Thiệt sự nhiều bạn muốn làm kỹ sư cầu nối vì có nhiều mục đích, nhưng theo mình nghĩ cái chính và cái cũng ít người nói thẳng vì nó “vật chất” quá, đó là thu nhập – lý do này cũng chính đáng mà (cũng có bạn chỉ muốn qua Nhật gặp … thần tượng). So với mặt bằng lương chung của dân coder thì BrSE cao hơn hẳn.

Theo số liệu thống kê mình có đọc được ở mấy trang báo lá mía thì mức lương rơi vào khoảng 5 đến 10 triệu đối với kinh nghiệm 3 năm trở lại, 3 đến 5 năm thì 10 đến 15tr, còn trên 5 năm thì 15 đến 20.

Đây là mức ở Đà Nẵng, Hà nội hệ số lương là 1.3 còn Sài gòn thì 1.5, tức là gấp rưỡi DN vì vật giá cao hơn. Còn lương BrSE thì sao ? khoảng 40 đến 80 tr (20~40 man) / tháng tại JP, 20 – 40 triệu/ tháng tại VN. Cao hơn gấp mấy lần so với cu đơ thường (không có ý so sánh j cả, kiểu như kem đánh răng PS vs kem thường, chà trắng răng thơm miệng vậy thôi ^^). Nếu tiết kiệm thì mỗi năm vẫn dư ra 200 – 400tr, làm 3 – 5 năm là mua được nhà, cưới được vợ, tậu được xe công nông rồi 

Xem thêm các việc làm BrSE hấp dẫn tại TopDev

Con Đường

Tản Mạn Về Con Đường Trở Thành BrSEĐường hoa tử đằng … đằng nào già rồi cũng tử nên trẻ cứ đi

Như trên mình vẽ ra cái đích, bây giờ bàn đến đường đi tới đó. Nhưng dù xuất phát điểm hiện tại đang ở mức nào thì chỉ cần thời gian với 1 chút quyết tâm là bắn nhanh thôi. Thực ra vị trí này cũng chỉ tầm trung chứ chẳng cao xa gì cho cam nên nhấc chân lên đi vài bước là tới à !

Có IT – Không JP

Quay lại đoạn đầu bài, cậu em của thằng bạn mình nó đã làm trong công ty IT cũng 3 năm, CV mình xem qua cũng khá ngầu rồi, vấn đề còn lại chỉ là tiếng Nhật thôi.

Đặt giả sử bạn là sếp đi, có 1 mem kỹ thuật khá, tinh thần làm việc ngon lành nhưng tiếng nhật mới N3 bạn có dám vác qua lấy dự án không ? lỡ em nó nghe sai truyền đạt trật cái thì bỏ mie luôn.

Nhưng có 1 chú lính khác, kỹ thuật tạm được, tiếng nhật N2 nói nghe rào rào (vì chú này cũng chăm … xem phim) thì dù nó có không muốn đi cũng năn nỉ : “em ráng qua vài tháng onsite lấy yêu cầu rồi mang về thôi, việc còn lại cứ để anh với mấy đứa khác lo”.

Có JP – Không IT

Còn cậu em thứ 2, đang là tu nghiệp sinh tại Nhật, chưa từng qua trường lớp đào tạo IT nhưng mê code. Em đúng là của hiếm rồi, nếu vượt qua được nền tảng cơ bản IT trong 1 năm mà không nản chí thì sau này em sẽ làm được việc lớn – BrSE chỉ là chuyện nhỏ thôi. Những thứ cần phải học trong năm 1 là : Tổng quan phần cứng – mềm -network, lập trình hướng đối tượng, cấu trúc dữ liệu và giải thuật, tổng quan hệ cơ sở dữ liệu. năm thứ 2 tự học chuyên sâu về ngôn ngữ như C#, Java …

Ngoài ra rảnh rỗi thì đọc mấy blog về công nghệ như VinaCode, techtalk hay blog của chú Hoàng – toidicodedao cũng rất hay. Tất cả đều phải tự học, google là chính. Nghề khác nói tự học có vẻ cao siêu chứ dân IT thì phần lớn kiến thức là tự học. Đang ở Nhật thì tận dụng cơ hội tranh thủ kiếm N1, rảnh rảnh ngoài giờ làm lê la ra mấy công viên, lễ hội … làm quen mấy em xinh xinh, luyện giao tiếp (chỉ giao tiếp thôi nhé, ko nên giao … cái khác) .

Khám phá việc làm Tiếng Nhật hấp dẫn tại TopDev

Tổng Kết

  • Thu nhập BrSE cao hơn cu đơ thường, kỹ năng đòi hỏi cũng cao tương đương
  • Tăng kỹ năng trước, thiếu IT học IT, thiếu JP học JP. Thu nhập sẽ tự tăng theo

Thêm 1 bật mí nhỏ : Làm BrSE nếu không thích qua JP cũng vẫn OK, làm tại chỗ chỉ liên lạc với khách hàng qua mail vs tài liệu. Ngoài lương cứng ra thì các công ty IT ở trong nước cũng có phụ cấp ngoại ngữ rất cao, N2 tầm 3-7 triệu/ tháng, còn N1 thì 5 – 15 triệu/tháng tùy công ty. Đó mới phụ cấp thôi nhé, còn lương vs thưởng là khác nữa.

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

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

 

Hướng dẫn từng bước lập trình web với Python

lập trình web với Python

Lập trình website nói chung và lập trình web site với Python hay bất cứ ngôn ngữ nào khác chưa bao giờ hết hot. Thời đại chuyển đổi số và số hóa toàn diện khắp mọi nơi như hiện nay, lập trình website nói riêng và lập trình nói chung trở thành kỹ năng không thể thiếu để tham gia vào quá trình chuyển đổi này.

Bài viết này sẽ hướng dẫn từng bước cho anh em lập trình web với Python.

Lập trình web với python

1. Lập trình web với Python liệu có khó?

Câu trả lời là không khó, bài viết này sẽ cung cấp đầy đủ thông tin cho anh em khi lựa chọn bắt đầu với Python. Với các nội dung dưới đây, anh em sẽ có cái nhìn đầy đủ kèm các bước để lập trình web với Python.

  • Tại sao lại lựa chọn Python?
  • Các framework nào có thể cân nhắc?
  • Khi đã lựa chọn framework, hành trình bắt đầu như thế nào?

Ngôn ngữ nào cũng vậy, trước khi bắt đầu ta luôn đánh giá và so sánh giữa các ngôn ngữ. Một số yếu tố có thể xem xét bao gồm:

  • Ngôn ngữ học có khó không?
  • Framework có hỗ trợ tốt không?
  • Khả năng mở rộng như thế nào?

Lựa chọn luôn cần lý do

  Python là gì? Tổng hợp kiến thức cho người mới bắt đầu

2. Tại sao lại là Python?

Như anh em đã biết, lựa chọn đi theo con đường phát triển web, anh em có vô vàn lựa chọn.

  • Lập trình web với Html, Css, JS thuần, anh nào làm giỏi cũng rất là ghê nha. Không bao giờ khinh thường html, css :d.
  • Với một số frontend framework thì anh em có thể go với Nuxt, với Reactjs
  • Với .net cũng có thể build website, mixed với Angular nữa thì bộ đôi song sát

Nói chung là có rất nhiều lựa chọn anh em có thể phát triển website của mình. Vậy câu hỏi đặt là là sao lại chọn Python. Tại sao lại là lập trình web với Python?.

Có 3 ý có thể giải thích cho việc lựa chọn Python để phát triển web không phải là một lựa chọn tồi.

  • Dễ để học: Anh em bắt đầu tìm hiểu về lập trình web với Python cũng biết Python là một trong những ngôn ngữ lập trình phổ biến nhất. Về cú pháp (common expressions), Python dễ học hơn nhiều so với Java hay C++. Python cũng là ngôn ngữ phố biến nhất thường được học cho anh em mới bắt đầu. Ngôn ngữ dễ để bắt đầu.
  • Hệ sinh thái và thư viện phong phú: Tùy vào website anh em phát triển, tuy nhiên hiếm có dự án nào mà không sử dụng lib, điều đó cho biết lib có vai trò cực kì quan trọng trong phát triển phần mềm. Mà python thì có đầy đủ và cực nhiều các thư viện, ví dụ anh em có thể dùng Numpy và Pandas để phân tích toán học, Pygal để lập biểu đồ và SLQALchemy cho các truy vấn SQL.
  • Thời gian phát triển nhanh: Với một số dự án phát triển website, thời gian cũng là một yếu tố quan trọng cần xem xét tới. Với Python, quy trình và cách thức phát triển website đôi khi còn rõ ràng hơn cả Java hay một số ngôn ngữ lập trình khác.

Với 3 lý do này, Python rõ ràng trở thành ngôn ngữ đáng cân nhắc để phát triển website.

Đã chọn được rồi, vậy Python Web Framework nào ta có thể xem xét sử dụng?

  Python Lists: Append vs Extend (Có ví dụ)

3. Python framework để lập trình web với Python

Nhắc lại chút xíu về framework cho anh em nào mới.

Framework được hiểu như là bộ công cụ. Web framework là bộ các gói, các modules đã được viết sẵn, hỗ trỡ quá trình development. Những package hay modules này thì đã được test kỹ và sử dụng bởi rất nhiều lập trình viên kahcs. Việc này giúp cho quá trình lập trình web với Python nói chung và các ngôn ngữ khác nói riêng trở nên nhanh chóng hơn.

Rồi, giờ qua framework nào dùng để lập trình web với Python?.

Nguồn ảnh: activestate.com

Một số tiêu chí cân nhắc khi lựa chọn framework

  • URL routing – Chuyển hướng URL
  • HTTP requests và responses – Xử lý request và response khi gọi API
  • Accessing databases – Truy cập hệ cơ sở dữ liệu
  • Web security – Bảo mật website

Đầu tiên, không thể không nói tới Django

3.1 Django

Django is a Python web framework is high-level framework that “encourages rapid development and clean, pragmatic design.” It’s fast, secure, and scalable. Django offers strong community support and detailed documentation. Django là web framework và nó miễn phí, là framework cấp cao, “khuyến khích phát triển nhanh và rõ ràng, thực dụng. Django cũng có một cộng đồng hỗ trợ lớn và các tài liệu chi tiết.

Về độ phổ biến thì Django không hề kém cạnh các framework frontend khác như Nuxtjs hay Reacjs. Django hiện tại đang được sử dụng ở Instagram, Dropbox, Pinterest, và Spotify. Toàn các product sừng sỏ.

python diango

3.2 Flask

Flask hơi khác chút xíu, Falsk là microframework, chính vì vậy Flask đôi khi thua thiệt so với Django khi so sánh về các modules hỗ trợ như web template, account authorization (phân quyền tài khoản), và xác thực tài khoản.

Triết lý của ông Flask này theo kiểu là build core, cái cốt lỗi thì build chuẩn, giúp anh em phát triển có thể dễ dàng maintain sau này. Nếu bước đầu tiên phát triển website với Flask nó đã tốt. Flask hiện tại đang được Netflix, Linkedin và Uber sử dụng.

  Các vòng lặp trong Python

4. Road map để lập trình web với Python

Dưới đây là lộ trình anh em có thể thử để trở thành lập trình viên Python phát triển website. Lộ trình này bắt đầu từ những điều cơ bản nhất. Rất dễ để áp dụng cho anh em mới bắt đầu

4.1 HTML,CSS

Không sai, chính là HTML và CSS, bất trì lập trình viên nào phát triển website cũng cần tới HTML và CSS. Hai cái này là gốc và là cái căn bản nhất mà lập trình viên Frontend cần biết.

Sau khi đã hiểu về HTML, CSS, anh em cũng nên tìm hiểu qua DOM và cách browser render website. Nghe thì có vẻ là dễ nhưng không phải lập trình viên nào cũng biết, cùng tìm hiểu sau về phần này.

4.2 Javascript

Nắm chắc HTML, CSS là tốt, nhưng chưa đủ. Để trở thành lập trình viên lập trình web với Python ta cần tới Javascript. Với Javascript, một số khái niệm cần được tìm hiểu và nắm thật chắc

  • Data types – cấu trúc dữ liệu
  • Variables – biến
  • General conventions – các cú pháp cơ bản
  • String manipulation – làm việc với chuỗi
  • Arithmetic and operators – các biểu thức
  • Loops – vòng lặp

Javascript nói dễ có dễ, nói khó có khó . Để trở thành master thì không phải đơn giản, đòi hỏi thời gian công sức tìm hiểu và thực hành nhiều.

4.3 Jquery và frontend framework

Sau khi đã nắm chắc Javascript, anh em có thể tìm hiểu thêm Virtual DOM, các framework như Nuxt hay React, những framework này thực sự đã hoạt động như thế nào?

Đơn cử như câu hỏi: Làm sao react có thể compare giữa Virtual Dom và Dom để biết element nào đã thay đổi?.

Lập trình web với python JavaScript HTML DOM. Nguồn ảnh: w3schools.com

Bắt đầu với JS đã là tốt, nhưng đôi khi phải hiểu sâu các framework để trở thành FullStack Developer.

4.4 Python

Sau khi đã thành thạo một vài frontend framework, tất nhiên là lập trình web với Python phải sử dụng ngôn ngữ Python.

Python nền là cực kỳ quan trọng, tuy nhiên với kiến thức đã có sẵn ở bước số 3.3, Python không hề khó để nắm bắt. Học các nguyên tắc cơ bản sẽ giúp bạn chuẩn bị cho Django, vì vậy anh em sẽ không phải đau đầu khi bắt đầu.

4.5 Django + Database

Cuối cùng là Django và Database, bước này anh em sẽ được làm quen với các hệ cơ sở dữ liệu, SQLite. Với Django đóng vai trò BE, lập trình web lúc này trở nên hứng thú hơn. Anh em có thể apply các mô hình kinh doanh, các logic business phức tạp.

5. Bắt đầu project đầu tiên cùng Python Django

Tạm thời viết ví dụ start project, ở bài viết số hai sẽ đi cùng anh em tìm hiểu sâu hơn về Python Flask nha. Bài hơi dài rồi :d. Anh em chờ theo dõi bài 2 của series này nha.

Cảm ơn anh em đã đọc bài – Thank you for your time to read – Happy coding!

Tác giả: Kiên Nguyễn

Ứng tuyển ngay hàng loạt IT Job Hot trên TopDev!

Kết nối DB ORACLE từ PHP trên CENTOS 7, 8

KẾT NỐI DB ORACLE TỪ PHP TRÊN CENTOS 7, 8

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

Để kết nối được đến cơ sở dữ liệu Oracle từ CentOS 7, 8, bạn cần cài đặt Oracle InstantClient. Và bạn cũng cần phần mở rộng OCI8 để gọi từ PHP.

Cài đặt Oracle InstantClient

Với el8 / CentOS 8 / stream / Rocky / Almalinux

Trước hết, cần tải các gói cần thiết.

$ cd /usr/local/src
$ wget https://download.oracle.com/otn_software/linux/instantclient/215000/oracle-instantclient-basic-21.5.0.0.0-1.el8.x86_64.rpm
$ wget https://download.oracle.com/otn_software/linux/instantclient/215000/oracle-instantclient-sqlplus-21.5.0.0.0-1.el8.x86_64.rpm
$ wget https://download.oracle.com/otn_software/linux/instantclient/215000/oracle-instantclient-devel-21.5.0.0.0-1.el8.x86_64.rpm
$ wget https://download.oracle.com/otn_software/linux/instantclient/215000/oracle-instantclient-jdbc-21.5.0.0.0-1.el8.x86_64.rpm

Sau đó, cài đặt bằng lệnh sau.

$ cd /usr/local/src
$ dnf localinstall oracle* --nogpgcheck

Với el7 / CentOS 7

Bạn cũng cần tải các gói cần thiết trước.

$ cd /usr/local/src
$ wget https://download.oracle.com/otn_software/linux/instantclient/215000/oracle-instantclient-basic-21.5.0.0.0-1.x86_64.rpm
$ wget https://download.oracle.com/otn_software/linux/instantclient/215000/oracle-instantclient-sqlplus-21.5.0.0.0-1.x86_64.rpm
$ wget https://download.oracle.com/otn_software/linux/instantclient/215000/oracle-instantclient-devel-21.5.0.0.0-1.x86_64.rpm
$ wget https://download.oracle.com/otn_software/linux/instantclient/215000/oracle-instantclient-jdbc-21.5.0.0.0-1.x86_64.rpm

Rồi cài đặt bằng lệnh sau.

$ cd /usr/local/src
$ yum localinstall oracle* --nogpgcheck

Cài đặt OCI8 qua lệnh PECL

Sau khi cài đặt Oracle InstantClient, bạn cần cài đặt phần mở rộng OCI8 để kết nối đến cơ sở dữ liệu Oracle từ PHP. Việc cài đặt phiên bản nào của OCI8 sẽ phụ thuộc vào phiên bản PHP bạn đang sử dụng.

Bạn có hai cách để cài là dùng lệnh PECL hoặc tải package về và tự build bằng phpize và make.

Trước hết, hãy tìm hiểu cách thứ nhất. Bạn gõ như sau.

$ pecl install oci8

Nếu dùng PHP 7.x, thay vì oci8, bạn dùng oci8-2.2.0. Tức là câu lệnh bên trên sẽ trở thành như sau.

$ pecl install oci8-2.2.0

Có một lưu ý, trong trường hợp bạn dùng tường lửa, bạn cần thiết lập proxy PEAR trước khi chạy lệnh PECL trên.

$ pear config-set http_proxy http://my-proxy.example.com:80/

Xem ngay tin tuyển dụng PHP lương cao trên TopDev

Cài đặt OCI8 dùng phpize và make

Đầu tiên, chuyển đến /usr/local/src.

$ cd /usr/local/src

Tải bản OCI8 tương ứng với phiên bản PHP

PHP 7.x

$ wget https://pecl.php.net/get/oci8-2.2.0.tgz

PHP 8.0

$ wget https://pecl.php.net/get/oci8-3.0.1.tgz

PHP 8.1

$ wget https://pecl.php.net/get/oci8-3.2.1.tgz

Giải nén file vừa tải bằng tar, rồi chuyển đến thư mục vừa được giải nén. Chẳng hạn, với trường hợp PHP 7.x.

$ tar -zxvf oci8-2.2.0.tgz
$ cd oci8-2.2.0

Build

Dùng phpize và make để build. Bạn có thể cần cài đặt hai phần mềm này qua yum (hoặc có thể là hậu duệ của nó — dnf nếu bạn dùng CentOS 8). Nếu bạn chưa biết thì yum (hay dnf) là trình quản lý gói, một “App Store” trên CentOS. Nó giúp bạn cài đặt các phần mềm cần thiết.

Chạy phpize và configure.

$ phpize
$ ./configure

Trong trường hợp bạn dùng php selector hay php-fpm, bạn cần cung cấp một đường dẫn cụ thể.

Với php selector.

$ /opt/alt/php74/usr/bin/phpize
$ ./configure --with-php-config=/opt/alt/php74/usr/bin/php-conf

Với php-fpm.

$ /opt/alt/php-fpm74/usr/bin/phpize
$ ./configure --with-php-config=/opt/alt/php-fpm74/usr/bin/php-config

Ví dụ bên trên dành cho PHP 7.4. PHP 8.0 và PHP 8.1 cũng tương tự.

Sau khi chạy phpize và configure, bạn cần chạy make.

$ make && make install

Config php/php-fpm

Sau khi cài OCI8 xong, bạn phải chỉnh sửa php.ini để có sử dụng. Thường đường dẫn sẽ là /usr/local/php/php.ini. Bạn thêm dòng sau.

extension=oci8.so

Với php-fpm, phải chỉnh sửa /etc/php-fpm.d/www.conf thêm dòng sau.

env[LD_LIBRARY_PATH] = /usr/lib/oracle/21/client64/lib:$LD_LIBRARY_PATH

Tiếp theo, hãy khởi động lại php/php-fpm. Bây giờ, bạn có thể sử dụng OCI8 để kết nối tới cơ sở dữ liệu Oracle được rồi. Nếu kiểm tra phpinfo sẽ thấy OCI8 đã enable.

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

Xem thêm:

Đừng bỏ lỡ việc làm IT lương cao, đãi ngộ hấp dẫn trên TopDev

9 kênh tuyển dụng IT hiệu quả bạn nên sử dụng

kênh tuyển dụng IT

Khan hiếm nhân lực IT hiện đang là mối quan tâm hàng đầu của nhiều doanh nghiệp. Thêm vào đó, đặc thù tìm việc của lập trình viên IT không giống những ngành khác. Điều này tạo nên những khó khăn và áp lực cho bộ phận nhân sự trong quá trình tuyển dụng. Hiểu được mối quan tâm của anh chị nhân sự, TopDev đưa ra chủ đề “Các kênh tuyển dụng IT hiệu quả”. Hãy cùng theo dõi!

Trước tiên để tuyển dụng hiệu quả, ta hãy xem xét hành vi tìm việc của ứng viên IT. Theo báo cáo Thị trường IT Việt Nam năm 2021 của TopDev cho thấy các trang web việc làm (51,2%) là kênh ưa thích của lập trình viên (51,2% câu trả lời), tiếp theo là cộng đồng CNTT (29,3%), sau đó là mạng xã hội (Facebook, LinkedIn) (22,3%) sự kiện, hội thảo công nghệ (21,4%).

các kênh tuyển dụng IT

Trang nghề nghiệp của công ty cũng nằm trong top kênh tìm kiếm việc làm phổ biến nhất cho các lập trình viên. Hackathon hay network cá nhân tuy không phổ biến bằng nhưng cũng là những kênh mà nhà tuyển dụng có thể cân nhắc khi muốn tiếp cận và tìm kiếm ứng viên CNTT.

Cụ thể ưu nhược điểm từng kênh này là gì? Nhà tuyển dụng nên lựa chọn kênh nào cho doanh nghiệp? Mời bạn tiếp tục theo dõi thông tin dưới đây.

1. Đăng tin trên những nền tảng tuyển dụng IT

Nền tảng tuyển dụng IT là nơi đăng tất cả các tin tuyển dụng của nhiều doanh nghiệp khác nhau có nhu cầu tuyển nhân lực chuyên ngành công nghệ thông tin. Tùy vào mỗi nền tảng mà bạn sẽ chi trả những mức phí khác nhau cho tin đăng tuyển dụng của doanh nghiệp. 

Đối với ứng viên đây là kênh tìm việc phổ biến. Khi có nhu cầu việc làm, lập trình viên thường có xu hướng tìm kiếm trên những trang web này và ứng tuyển trực tiếp trên website. Điều này xuất phát từ nhu cầu sẵn có nên ứng viên về từ nguồn này khá đa dạng và có chất lượng ổn định. 

Ngoài những thế mạnh nêu trên , đăng tuyển qua trang web IT còn có lợi ích gì khác không? Lấy ví dụ như TopDev – một trong những nền tảng tuyển dụng IT phổ biến nhất hiện nay. 

trang tuyển dụng IT TopDev

Ưu điểm

Những ưu điểm của nền tảng tuyển dụng IT TopDev mà nhà tuyển dụng nên cân nhắc như:

Tiếp cận đúng đối tượng

Tệp người dùng chính của nền tảng tuyển dụng IT là lập trình viên, những người quan tâm đến công nghệ. Mỗi tháng, nền tảng tuyển dụng đạt đến hàng trăm ngàn lượt truy cập. Điều này đồng nghĩa với việc, tin tuyển dụng của doanh nghiệp không chỉ tiếp cận đúng người mà còn tập trung với số lượng lớn.

Tăng độ phủ thương hiệu tuyển dụng

Ngoài việc đăng tuyển trên website, tin tuyển dụng của doanh nghiệp tại TopDev còn được truyền thông trên các trang mạng xã hội như Facebook, Linkedin, hay qua email. Từ đó, gia tăng độ nhận diện thương hiệu công ty.

Mặt khác, khi tìm kiếm việc làm ứng viên không chỉ xem xét mô tả vị trí công việc mà còn để tâm đến phúc lợi, môi trường làm việc của doanh nghiệp. Trường hợp, vị trí đăng tuyển chưa phù hợp với ứng viên đó, nhưng trong nhận thức họ đã dành một chỗ cho doanh nghiệp của bạn.

Các công việc đa dạng level

Bạn muốn đón đầu một nhân tài IT mới? Bạn đang mong đợi một IT Manager với kinh nghiệm dày dạn? Nền tảng TopDev là nơi phù hợp đăng tuyển việc làm IT mọi cấp độ. Từ ứng viên mới ra trường hay cấp bậc quản lý, bạn đều có thể cân nhắc sử dụng kênh tuyển dụng IT hiệu quả này.

Nhược điểm

Dĩ nhiên, bạn sẽ phải chỉ trả một khoản chi phí cho dịch vụ đăng tin tuyển dụng. Bên cạnh đó bạn cũng cần nghiên cứu và chọn lọc những nền tảng uy tín phù hợp với nhu cầu tuyển dụng của doanh nghiệp. 

Nếu bạn mong muốn tiết kiệm thời gian và công sức trong quá trình tìm kiếm nhân lực IT, hãy tham khảo dịch vụ tin đăng của TopDev. Là một trong những nền tảng tuyển dụng IT uy tín hàng đầu hiện nay, TopDev hỗ trợ bạn trên con đường tìm kiếm ứng viên IT tiềm năng. 

Với trung bình 30,000 lượt truy cập mỗi ngày trong đó có đến trên 90% là lập trình viên sẽ giúp bạn rút ngắn thời gian tuyển dụng, bên cạnh đó thương hiệu doanh nghiệp cũng nhận được sự chú ý của nhiều ứng viên tiềm năng. Ngoài ra, TopDev đưa ra rất nhiều ưu đãi giúp doanh nghiệp tiết kiệm phần nào chi phí nhân sự. Tham khảo dịch vụ và ưu đãi tại đây!

2. Cộng đồng CNTT/ Blog

Đây là kênh tìm việc phổ biến thứ hai của dân IT. Sở dĩ, cộng đồng CNTT hoặc blog là nơi lập trình viên có thể tìm kiếm tất tần tật các nội dung thuộc phạm trù IT như cách sửa lỗi lập trình, kinh nghiệm học lập trình, cách viết CV, bí kíp trả lời phỏng vấn. Vì thế, theo thói quen họ cũng sẽ vào đây tìm kiếm cơ hội việc làm.

3. Mạng xã hội

Facebook, Zalo hay Linkedin đều là những nơi tiếp cận ứng viên nhanh chóng. Nhà tuyển dụng/ ứng viên thường tạo một profile rõ ràng, thu hút, sau đó tham gia vào những group tìm việc làm, thỉnh thoảng chia sẻ những kiến thức hữu ích, từ đó kết nối với nhiều ứng viên, nhà tuyển dụng trong ngành.

Đối với nhiều doanh nghiệp đây là một kênh tuyển dụng tiềm năng khi tiếp cận được nhiều ứng viên trẻ và hầu như không mất phí. Tuy nhiên, đối với lập trình IT, sẽ khá khó khăn để tìm kiếm một ứng viên “chất lượng” qua Facebook hay Zalo bởi lập trình viên mong muốn được “săn đón” và sự đầu tư từ doanh nghiệp.

4. Sự kiện, hội thảo công nghệ

Sự kiện, hội thảo công nghệ không chỉ là nơi chia sẻ kinh nghiệm, cập nhật xu hướng công nghệ trong tương lai mà còn là nơi tạo dựng networking. Người tham gia sự kiện đều là những người chủ động tiếp thu kiến thức, chủ động tìm việc làm do đó nhà tuyển dụng sẽ dễ dàng tìm thấy ứng viên phù hợp.

Bên cạnh đó, do là sự kiện chuyên sâu nên sẽ thu hút nhiều “người trong ngành”, từ đó doanh nghiệp hoàn toàn có thể tiếp cận những lập trình viên nhiều kinh nghiệm. 

Nhà tuyển dụng có thể tham khảo những sự kiện Công nghệ lớn hằng năm như Vietnam Mobile Day, Vietnam Web Summit. Đây là hai sự kiện công nghệ được tổ chức với quy mô lớn quy tụ nhiều diễn giả đầu ngành cũng như thu hút rất nhiều lập trình viên và “mọt” công nghệ.

5. Trang web nghề nghiệp công ty

Trang tuyển dụng của công ty là một trong những kênh mà bạn nên đầu tư. Một giao diện thu hút, nội dung cụ thể và phúc lợi hấp dẫn sẽ giúp bạn gia tăng số lượng ứng tuyển. Tuy nhiên, đối với những doanh nghiệp chưa có thương hiệu hay startup, kênh tuyển dụng này sẽ không đạt hiệu quả cao.

6. Hackathon

Hackathon là sân chơi dành cho dân IT, tại đây các lập trình viên sẽ thực hiện một ý tưởng công nghệ để giải quyết một vấn đề nào đó, từ khâu lên kế hoạch đến bước hoàn thành.

Đây là nguồn cung cấp nhân lực IT chất lượng và đa dạng. Bằng hình thức tài trợ và truyền thông cơ hội việc làm, nhà tuyển dụng có thể thu về nhiều tài năng cho doanh nghiệp cũng như truyền thông thương hiệu hiệu quả.

7. Giới thiệu nội bộ

Tuyển dụng thông qua giới thiệu nội bộ được xem là kênh tuyển dụng IT hiệu quả và nhanh chóng. Dựa vào các mối quan hệ bạn bè, đồng nghiệp mà nhân viên trong công ty sẽ giới thiệu các ứng viên tiềm năng.

Ưu điểm của kênh này là dễ tìm được ứng viên trong thời gian ngắn và tỷ lệ ứng viên phù hợp cao. Tuy nhiên, nếu bạn tuyển dụng với số lượng lớn thì đây chỉ là kênh hỗ trợ.

internal recruitment

8. Các công ty nhân sự, Headhunter

Headhunt sẽ là kênh tuyển dụng hiệu quả trong trường hợp bạn cần nhân lực IT cấp cao hoặc vị trí đặc thù. Bạn sẽ không phải mất thời gian tìm kiếm, lọc hồ sơ,… Headhunter sẽ đảm nhận những nhiệm vụ này, doanh nghiệp chỉ cần lựa chọn ứng viên và lên lịch phỏng vấn.

Tuy nhiên, dây là kênh tuyển dụng khá mới ở Việt Nam và chi phí khá tốn kém.

9. Liên kết với các trường đại học

Hầu hết mỗi trường đại học đều liên kết với các doanh nghiệp. Những chương trình như tài trợ cuộc thi, ngày hội việc làm, hội thảo hướng nghiệp,… giúp bạn gặp gỡ và tìm kiếm được những ứng viên phù hợp.

Đây là kênh tuyển dụng mang đến nguồn nhân lực trẻ đầy tiềm năng tuy nhiên sẽ khá khó khăn để nhà tuyển dụng tìm kiếm được ứng viên có nhiều kinh nghiệm.

Trên đây là 9 kênh tuyển dụng IT hiệu quả mà nhà tuyển dụng nên cân nhắc. Một lời khuyên nhỏ là anh chị hãy làm rõ nhu cầu tuyển dụng của doanh nghiệp trước sau đó mới tìm hiểu đến các kênh tuyển dụng và cân nhắc theo nhu cầu ấy.

kênh tuyển dụng IT

Trường hợp nhà tuyển dụng mong muốn tuyển dụng đa kênh với mức chi phí tối ưu, mời anh chị tham khảo dịch vụ đăng tuyển IT tại TopDev! TopDev phát triển sản phẩm cả website và ứng dụng di động tạo điều kiện thuận lợi cho quá trình tìm việc của ứng viên. Đi kèm là hệ sinh thái fanpage với lượt follow lớn trên mạng xã hội, trong đó Facebook Fanpage TopDev với tổng trên 150,000 lượt like, Linkedin TopDev gần 10,000 follow.

Thêm vào đó, TopDev còn cung cấp cả blog kiến thức IT, kỹ năng mềm, mẹo phỏng vấn cho lập trình viên, đóng góp một phần để xây dựng cộng đồng IT Việt Nam.  Ngoài ra, TopDev là đơn vị tổ chức hai sự kiện công nghệ lớn nhất hiện nay là Vietnam Mobile Day và Vietnam Web Summit, nơi thuận lợi để bạn gia tăng độ nhận diện thương hiệu.

Cuối cùng nhưng không kém phần quan trọng đó là TopDev luôn sở hữu nhiều ưu đãi hấp dẫn cho các gói đăng tin chất lượng. Tham khảo dịch vụ và ưu đãi ngay tại đây!


Tuyển Dụng Nhân Tài IT Cùng TopDev
Đăng ký nhận ưu đãi & tư vấn về các giải pháp Tuyển dụng IT & Xây dựng Thương hiệu tuyển dụng ngay!
Hotline: 028.6273.3496 – Email: contact@topdev.vn
Dịch vụ: https://topdev.vn/page/products

Giới thiệu về Spring Integration

Gioi thieu spring integration

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

Mình đã giới thiệu với các bạn về MuleSoft, một low code platform giúp chúng ta hiện thực các ứng dụng Enterprise Service Bus với nhiều Enterprise Integration Pattern một cách dễ dàng. Vấn đề là MuleSoft không free mặc dù nó cũng có bản community nên chúng ta cần có những giải pháp ít tốn chi phí hơn. Một trong số những giải pháp mà mình muốn giới thiệu với các bạn trong bài viết này là Spring Integration. Cụ thể là như thế nào? Chúng ta hãy cùng nhau tìm hiểu trong bài viết này các bạn nhé!

Cơ bản về Spring Integration

Điều đầu tiên mà các bạn cần biết là, tương tự như MuleSoft, Spring Integration giúp chúng ta hiện thực các ứng dụng middleware, integrate các ứng dụng trong một hệ thống với nhau. Nó sử dụng messaging strategy để giữ và truyền thông tin giữa các component với nhau trong ứng dụng middleware hoặc giữa các ứng dụng với nhau.

Các khái niệm chính trong Spring Integration mà các bạn cần biết là MessageMessage Channel và Message EndpointMột message sẽ được gửi tới một Message Endpoint, các Message Endpoints sẽ được kết nối với nhau thông qua Message Channels, một Message Endpoint có thể nhận Message từ một Message Channel.

Spring Integration

Message

Một Message trong Spring Integration sẽ chứa các thông tin mà qua mỗi một Endpoint, các thông tin đó có thể sẽ bị thay đổi. Cấu trúc của một Message bao gồm Header và Payload như sau:

Interface Message của Spring Integration định nghĩa thông tin Message này đó các bạn!

package org.springframework.messaging;
 
public interface Message<T> {
 
  T getPayload();
 
  MessageHeaders getHeaders();
}

Implementation chính của interface Message này là class GenericMessage.
Thường thì Header của Message sẽ chứa các thông tin overview về message. Như các bạn thấy, class MessageHeaders sẽ chứa những thông tin overview này. Bản chất thì class MessageHeaders này implement interface Map với thông tin là các cặp key và value. Các bạn lưu ý là class MessageHeaders là immutable class, chúng ta không thể thay đổi thông tin trong Header một khi Message đã được khởi tạo.

Payload sẽ chứa thông tin chính của Message, được định nghĩa sử dụng bất kỳ loại dữ liệu Java nào mà các bạn muốn.

Message Channel

Message Channel dùng để connect các Message Endpoint với nhau, các Message Endpoint sẽ sử dụng Message Channel để truyền Message cho nhau.

Một Message Channel có thể có một (Point-to-Point Message Channel) hoặc nhiều Message Endpoint subscribe vào để nhận Message.

Một Message Endpoint thường sẽ có một Inbound Message Channel và một Outbound Message Channel. Nếu một Message Endpoint không có Outbound Message Channel thì Spring Integration sẽ tự động tạo tạm một Message Channel để trả về kết quả.

Message Endpoint

Mỗi khi Message được một Message Endpoint handle, tuỳ theo business requirement, Message sẽ được enrich, transform và thay đổi thông tin mà nó đang nắm giữ.

Ví dụ như nếu Message của các bạn đang chứa ID của sinh viên cần lấy thông tin trong database thì khi đi qua Message Endpoint lấy thông tin từ database, Message ở Outbound Message Channel của Message Endpoint lấy thông tin từ database này sẽ chứa thông tin sinh viên, không còn chứa ID của sinh viên nữa.

Các Message Endpoints có thể là:

  • Channel adapter: kết nối ứng dụng với một external system theo một chiều, chỉ gửi Message đi, không nhận respone Message về.
  • Gateway: kết nối ứng dụng với một external system theo hai chiều, gửi Message đi và nhận respone Message về.
  • Service Activator: được sử dụng để gọi một phương thức của một đối tượng Java.
  • Transformer: chuyển đổi nội dung của một Message.
  • Filter: xác định có tiếp tục process Message hay không?
  • Router: quyết định Message Channel nào mà Message sẽ được gửi.
  • Splitter: chia nhỏ Message ra thành nhiều phần.
  • Aggregator: combine vài Message thành một Message duy nhất.

Java job đãi ngộ hấp dẫn đang chờ bạn ứng tuyển tại đây

Ứng dụng ví dụ

Để có cái nhìn sơ qua về cách Spring Integration làm việc, mình sẽ làm một ứng dụng cơ bản, cứ sau 5s sẽ gửi một Message với payload là tên của mình từ Message Endpoint này sang Message Endpoint khác để Message Endpoint khác đó in ra dòng chữ “Hello Khanh from Huong Dan Java” các bạn nhé!

Mình sẽ tạo một Maven project

 

với Spring Integration dependency để làm ví dụ:

<dependency>
  <groupId>org.springframework.integration</groupId>
  <artifactId>spring-integration-core</artifactId>
  <version>5.5.12</version>
</dependency>

Có 2 cách để cấu hình Spring Integration: sử dụng tập tin XML và sử dụng Java code. Trong bài viết này, chúng ta sẽ sử dụng tập tin XML các bạn nhé!

Mình sẽ tạo mới tập tin spring-integration.xml trong thư mục src/main/resources để cấu hình cho Spring Integration, với nội dung ban đầu như sau:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:int="http://www.springframework.org/schema/integration"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-5.2.xsd">
 
</beans>

Khác với Spring framework schema, tập tin http://www.springframework.org/schema/beans/spring-beans.xsd luôn được cập nhập đến latest version của Spring, đối với Spring Integration schema, các bạn cần sử dụng latest version, hiện tại là 5.2 http://www.springframework.org/schema/integration/spring-integration-5.2.xsd, các bạn nhé!

Đầu tiên, mình sẽ định nghĩa Message Channel trong Spring container làm nhiệm vụ truyền Message từ Message Endpoint tạo payload qua Message Endpoint in dòng chữ “Hello Khanh from Huong Dan Java “!

Các bạn sử dụng tag <int:channel> để định nghĩa một Message Channel các bạn nhé:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:int="http://www.springframework.org/schema/integration"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-5.2.xsd">
 
  <int:channel id="channel" />
  
</beans>

Các Message Channel identify với nhau bằng bean ID của các Message Channel đó. Trong ví dụ này, mình chỉ cần tạo một Message Channel là đủ, các bạn có thể tạo nhiều nếu muốn!

Để ứng dụng của chúng ta có thể cứ sau 5s thì gửi một Message, chúng ta sẽ định nghĩa một Message Endpoint sử dụng Polling Channel Adapter của Spring Integration với tag <int:inbound-channel-adapter/> như sau:

<int:inbound-channel-adapter channel="channel" expression="{'Khanh'}">
  <int:poller fixed-delay="5000" />
</int:inbound-channel-adapter>

Thuộc tính expression sẽ giúp chúng ta định nghĩa data sẽ được tạo ra khi Poller được trigger. Giá trị của thuộc tính expression này hỗ trợ Spring Expression Language, nên các bạn có thể bất kỳ giá trị nào, miễn thoả mãn Spring Expression Language là được!

Thuộc tính channel dùng để định nghĩa Message Channel mà data được tạo ra sẽ được chuyển đi. Giá trị của thuộc tính channel này là bean ID của Message Channel các bạn nhé!

Bên trong tag <int:inbound-channel-adapter/>, chúng ta định nghĩa tag <int:poller/> với thuộc tính fixed-deplay có giá trị là 5s để sau 5s thì Poller của chúng ta sẽ được trigger đó các bạn!

Bây giờ chúng ta sẽ sử dụng Logging Channel Adapter với tag <int:logging-channel-adapter/> để consume Message từ Polling Channel Adapter và in ra dòng chữ “Hello Khanh from Huong Dan Java”, như sau:

<int:logging-channel-adapter channel="channel"
  logger-name="com.huongdanjava.springintegration"
  expression="'Hello '.concat(payload).concat(' from Huong Dan Java')" />

Logging Channel Adapter sẽ consume Message từ channel có bean ID là “channel”, data được log sẽ được lấy từ thuộc tính expression của tag <int:logging-channel-adapter/>. Các bạn cần thêm tập tin cấu hình của Logging Framework để log message theo ý của mình nhé!

Để chạy ứng dụng này, mình sẽ tạo một class với main() method với nội dung như sau:

package com.huongdanjava.springintegration;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Application {
 public static void main(String[] args) {
    new ClassPathXmlApplicationContext("spring-integration.xml");
  }
}

Kết quả khi chạy ứng dụng trên như sau:

Lập trình C++ cơ bản – Tất tần tật kiến thức về C++

lập trình c++ cơ bản

Lập trình C++, chà, ngôn ngữ thì lâu đời rồi nhưng giờ vẫn còn nhiều anh em học. Thật lòng mà nói thì bắt đầu với C++ lúc làm quen với lập trình không phải không tốt. Cùng TopDev tìm hiểu các kiến thức cơ bản về ngôn ngữ C++ cũng như điểm qua các ứng dụng có thể viết bằng C++ cũng như cơ hội việc làm hiện nay.

c++ là gì
C++ là gì? Tổng hợp kiến thức lập trình C++

C++ là gì?

C++ (còn được viết là C plus plus hay CPP) là một ngôn ngữ lập trình hướng đối tượng (OOP) được nhiều người xem là ngôn ngữ tốt nhất để tạo các ứng dụng quy mô lớn. C++ là một phần mở rộng của ngôn ngữ C.

C++ là một loại ngôn ngữ lập trình bậc trung (middle-level), mang cả tính chất của ngôn ngữ lập trình bật thấp như pascal hay C và ngôn ngữ lập trình bậc cao (C#, Java, Python…)

C++ cho phép các nhà phát triển phần mềm định nghĩa các kiểu dữ liệu của riêng họ và thao tác chúng bằng các hàm và phương thức. Nó cũng cho phép lập trình cấp thấp và cung cấp quyền truy cập vào bộ nhớ, giúp thực thi mã nhanh chóng và hiệu quả. Nó cũng hỗ trợ lập trình tổng quát bằng cách sử dụng các mẫu, cho phép mã được viết dưới dạng tổng quát và tái sử dụng cho các kiểu dữ liệu khác nhau.

C++ được sử dụng trong các lĩnh vực như phần mềm hệ thống, phát triển game, hệ thống nhúng, tính toán khoa học và các ứng dụng hiệu suất cao. Thư viện chuẩn của C++ cung cấp một loạt các tiện ích và hàm mã hóa, giúp phát triển các hệ thống phần mềm phức tạp dễ dàng hơn. C++ có thể chạy trên nhiều nền tảng, bao gồm Linux, Mac và Windows.

Lịch sử hình thành của lập trình C++

C++ được phát triển bởi nhà khoa học máy tính Đan Mạch Bjarne Stroustrup vào năm 1983 tại Bell Labs như một phần mở rộng của ngôn ngữ lập trình C. Stroustrup muốn kết hợp các tính năng của lập trình hướng đối tượng từ ngôn ngữ Simula với hiệu suất và tính linh hoạt của C.

Phiên bản đầu tiên của C++ được phát hành vào năm 1985. C++ được chuẩn hóa lần đầu tiên vào năm 1998 bởi Tổ chức Tiêu chuẩn hóa Quốc tế (ISO) dưới tên ISO/IEC 14882:1998. Các phiên bản tiếp theo bao gồm C++03, C++11, C++14, C++17 và gần đây nhất là C++20 được phát hành vào tháng 12 năm 2020. C++ đã trở thành ngôn ngữ lập trình mạnh mẽ và linh hoạt, được sử dụng rộng rãi trong nhiều lĩnh vực khác nhau.

Ứng dụng của lập trình C++

Ứng dụng của ngôn ngữ C++
Ứng dụng của ngôn ngữ C++

C++ được sử dụng theo nhiều cách khác nhau để tận dụng tính linh hoạt và hiệu suất của nó. Một số ứng dụng chính của C++ bao gồm:

  • Hệ điều hành (OS): Khả năng cấp thấp của C++ cho phép quản lý bộ nhớ hiệu quả và kiểm soát tài nguyên hệ thống, phù hợp cho phát triển các hệ điều hành.
  • Trò chơi và đồ họa: Hiệu suất cao của C++ và khả năng tương tác với phần cứng làm cho nó là lựa chọn tốt cho các engine game như Unreal Engine của Epic Games và Unity của Unity Technologies, cũng như các tác vụ lập trình đồ họa như render thời gian thực, xử lý hình ảnh và mô phỏng vật lý.
  • Hệ thống nhúng: C++ thường được sử dụng trong phát triển các hệ thống nhúng, như thiết bị y tế, hệ thống ô tô và các thiết bị Internet of Things.
  • Thư viện phần mềm: C++ là nền tảng cho nhiều thư viện cấp cao, như Boost và Thư viện Mẫu Chuẩn (STL), cung cấp các cấu trúc dữ liệu và thuật toán tổng quát.
  • Tính toán hiệu suất cao (HPC): C++ phù hợp cho các ứng dụng HPC đòi hỏi hiệu suất tính toán tối đa và xử lý song song, thường được sử dụng trong mô phỏng khoa học, phân tích số và mô hình toán học.
  • Phát triển web: Mặc dù C++ không thường được sử dụng cho phát triển web, nó đóng vai trò quan trọng trong backend của các ứng dụng web, như máy chủ web và các giao thức mạng.
  • Lập trình hệ thống: C++ thường được sử dụng cho các tác vụ lập trình hệ thống, như driver thiết bị, giao thức mạng và tiện ích hệ thống.

Ưu điểm và nhược điểm của C++

Ưu điểm

Học lập trình C++ vẫn rất quan trọng và hữu ích trong thời điểm hiện tại vì các lý do sau:

  1. Hiệu suất cao: C++ cung cấp khả năng thao tác bộ nhớ cấp thấp và kiểm soát tối ưu tài nguyên hệ thống, phù hợp cho các ứng dụng yêu cầu hiệu suất cao như game, hệ thống nhúng và phần mềm hệ thống.
  2. Tính linh hoạt: Hỗ trợ lập trình hướng đối tượng, tổng quát và hàm, giúp giải quyết nhiều loại vấn đề khác nhau.
  3. Nền tảng vững chắc: Là nền tảng cho nhiều thư viện và framework, hỗ trợ phát triển phần mềm phức tạp.
  4. Ứng dụng rộng rãi: Sử dụng trong nhiều lĩnh vực như hệ điều hành, trình biên dịch, phần mềm mô phỏng khoa học, tài chính, và nhiều lĩnh vực khác.
  5. Tiêu chuẩn hóa và cộng đồng: C++ được tiêu chuẩn hóa bởi ISO và có một cộng đồng lập trình viên lớn hỗ trợ.

Nhược điểm

  1. Độ phức tạp và khó học: C++ có nhiều tính năng và cú pháp phức tạp, làm cho việc học và sử dụng trở nên khó khăn, đặc biệt đối với người mới bắt đầu.
  2. Quản lý bộ nhớ thủ công: C++ yêu cầu lập trình viên phải tự quản lý bộ nhớ, dễ dẫn đến rò rỉ bộ nhớ và các vấn đề khác nếu không được xử lý đúng cách.
  3. Rủi ro bảo mật: Truy cập trực tiếp vào bộ nhớ có thể gây ra các lỗi bảo mật nếu không được kiểm soát cẩn thận.
  4. Không có thu gom rác: Thiếu cơ chế tự động giải phóng bộ nhớ, lập trình viên phải tự tay giải phóng bộ nhớ không cần thiết.
  5. Cú pháp phức tạp: Cú pháp của C++ phức tạp hơn nhiều so với các ngôn ngữ lập trình khác, làm cho việc đọc và viết mã tốn nhiều thời gian hơn.
  6. Thời gian biên dịch lâu: C++ thường có thời gian biên dịch lâu hơn so với các ngôn ngữ có kiểu động hoặc biên dịch ngay lập tức.

Lương và Cơ Hội Việc Làm Lập Trình C++ tại Việt Nam

Mức Lương Lập Trình Viên C++

Mức lương của lập trình viên C++ tại Việt Nam phụ thuộc vào nhiều yếu tố như kinh nghiệm, vị trí làm việc và quy mô công ty. Dưới đây là một số mức lương phổ biến:

  • Mức lương trung bình: Lập trình viên C++ trung bình nhận khoảng 20-30 triệu VND/tháng.
  • Mức lương cao: Đối với các vị trí cao cấp hoặc ở các công ty lớn, mức lương có thể lên đến 50-60 triệu VND/tháng hoặc cao hơn.
  • Fresher: Mức lương cho lập trình viên mới ra trường (fresher) thường dao động từ 10-15 triệu VND/tháng.

Các công ty như NAKIVO, Pentalog Việt Nam, LG Electronics Development Vietnam và FOIS VIỆT NAM là những đơn vị trả lương cao nhất cho lập trình viên C++ với mức lương có thể lên tới 64 triệu VND/tháng​ (theo Tổng quan mức thu nhập lập trình viên – TopDev 2023)​.

Cơ Hội Việc Làm

Lập trình viên C++ có nhiều cơ hội việc làm trong các lĩnh vực khác nhau:

  • Phát triển phần mềm hệ thống: C++ được sử dụng rộng rãi trong phát triển hệ điều hành và phần mềm nhúng.
  • Game Development: Các công ty game lớn như VNG và Gameloft thường xuyên tuyển dụng lập trình viên C++ cho việc phát triển các trò chơi.
  • Tài chính và ngân hàng: Các hệ thống tài chính yêu cầu hiệu suất cao và độ tin cậy lớn thường sử dụng C++.
  • Công nghệ ô tô: C++ được sử dụng trong phát triển phần mềm cho xe tự lái và các hệ thống hỗ trợ lái xe.

Cú pháp và chương trình đầu tiên bằng lập trình C++

Bắt đầu với toàn lý thuyết khi muốn lập trình C++ cũng không phải là ý hay, tiếp theo là  cú pháp và biên dịch lập trình C++.

  • Viết chương trình mã code trong editor, anh em có thể dùng notepad hoặc bất cứ thứ gì nha. Lưu lại nó với format là .CPP, .C, .CP. Chỉ vậy là đủ
  • Cho anh em beginner thì không cần phức tạp, cứ up lên với online IDE nha (cái này là trình biên dịch online) dùng để chạy code của anh em. Link IDE đây nha anh em
  • Hiểu các thuật ngữ cơ bản

// Chương trình C++ in ra dòng chữ "Xin chao"
#include <iostream>
using namespace std;
  
// Main() function: nơi chương trình được thực thi
int main()
{
    // prints "Xin chao
    cout << "Xin chao";
  
    return 0;
}

Cứ code ở notepad chứ chưa cần cài IDE gì nha

Lập trình C++

Chương trình hello world (xin chào) là chương trình đầu tiên thường được viết khi học ngôn ngữ lập trình mới. Sau khi chạy và thấy kết quả output rồi.

Giờ tới lúc giải thích chi tiết cho anh em từng dòng code nha. Đừng hoang mang, mọi sự đều có lý do.

2. Giải thích từng dòng code

2.1 Dòng đầu tiên – comment

// Chương trình C++ in ra dòng chữ “Xin chao”: Dòng này là dòng comment (bình luận). Bình luận là cách mà anh em thêm nội dung bổ trợ để giải nghĩa cho code của mình. Dòng comment khi biên dịch chương trình sẽ không được để tâm tới. Nói chung là trình biên dịch sẽ bỏ qua nó, không quan tâm tới dòng này. Về khú pháp vì với lập trình C++, dòng comment luôn bắt đầu với ‘//’, không có ‘ nha anh em, hoặc có một cách khác là /*…*/, cái này là comment một khối.

// Chương trình C++ in ra dòng chữ "Xin chao"

Kiểu blog

/* Chương trình C++ in ra dòng chữ "Xin chao" */

2.2 Cần gì order giúp

#include: Trong ngôn ngữ lập trình C++ tất cả những dòng bắt đầu bằng dầu # sẽ được gọi bởi bộ tiền xử lý (gọi là biên dịch), thứ đọc code của anh em. Dòng #include này nói với trình biên dịch là cần iostream #include<iostream>. Trình biên dịch lúc nà hiểu lệnh này là, lúc mà biên dịch chương trình này á, làm ơn biên dịch giúp t luôn cả iostream. Về preprocessors anh em có thể tham khảo thêm More on Preprocessors.

#include <iostream>

À, vậy là với # thì cần gì mình cứ order với trình biên dịch, về sau anh em còn work nhiều với cái khác cần compile ha.

Tuyển dụng Fresher IT tại đây!

2.3 Viết nhiều không anh gì ơi?

Sau khi đã chuẩn bị nhiều thứ để sẵn sàng viết code, anh em vẫn thấy cái dòng số 3. Dòng này mới nhìn thì vô cùng khó hiểu.

using namespace std;

Bình tĩnh tui nói anh em nghe, trong Lập trình C++ á, namespace được dùng để khai báo sử dụng một tên không gian nào đó. Vẫn khó hiểu, ok

// file1.h
class LapTrinhCCongCong
{
};

// file1.h
class LapTrinhCCongCong
{
};

Phía trên đây ta thấy có 2 lớp có chung tên là LapTrinhCCongCong, trình biên dịch của C++ không thể hiểu được cái nào mới là đúng, lúc này namespace là thứ ta cần sử dụng tới.

#include <iostream>
using namespace std;
 
// Namespace n1
namespace LapTrinhCCongCong {
  void fun()
  {
      cout << "Xin Chao"
           << endl;
  }
}
 
// Sử dụng những thứ đã có ở namespace LapTrinhCCongCong
using namespace LapTrinhCCongCong;
 
// Driver Code
int main()
{
    // Gọi hàm fun đã khai báo sẵn trong namespace LapTrinhCCongCong
    fun();
    return 0;
}

Nhiều vị trí tuyển dụng C++ đãi ngộ tốt trên TopDev

2.4 Zô Zô, code thôi chứ khai báo đăng ký nhiều quá rồi

int main(): Dòng này khia báo một hàm có tên là main, chữ int đầu tiên có nghĩa là kiểu trả về và int này là integer (số). Hàm này bao gồm một loạt câu lệnh đằng sau nó. Anh em chú ý là tất cả các chương trình C++ đều phải bằng đầu với hàm main(), không quan trọng là hàm này nằm đâu, nhưng bắt buộc phải có hàm này.

int main()

2.5 Mở đóng, mở đóng mở

{ và }

Mở ngoặc là bắt đầu cho những gì sắp code ‘{‘ và dấu đóng ngoặc ‘}’ là kết thúc của hàm, ở đây là hàm main. Tất những gì anh em viết bên trong đóng và mở ngoặc đều là những câu lệnh sẽ được thực thi trong hàm main()

Tham khảo việc làm lập trình C trên TopDev

2.6 In xin chào đi thôi, lâu quá rồi

Bình tĩnh, giải thích từng dòng thì nó lâu, nhưng mà đã hiểu là hiểu sâu, hiểu rõ.

std::cout<<“Xin chao”;:  Dòng này nó nói với compiler là in ra đi, in giúp tao cái dòng “Xin chao” ở màn hình đi. Trong lập trình C++ thì xong này là một câu lệnh. Anh em nhớ tất cả câu lệnh trong C++ đều kết thúc bằng dấu chấm phẩy. Dấu chấm phẩy này sử dụng để trình compiler biết là nó kết thúc một câu lệnh. Dòng std::cout sử dụng để in ra những nội dung trong màn hình, nội dung này nằm trong hai dấu hai chấm.

Còn dấu bé?. Ok cái dấu bé này cho biết “<<” tất cả những gì sau nó sẽ hiển thị ra ngoài màn hình.

cout << "Xin chao";

2.7 Trả về gì đây? Trả về gì đây?

return 0; : Dòng này cũng là một câu lệnh nha anh em. Dòng này trả về giá trị cho hàm đã định nghĩa, ở đây là hàm name. Cứ thấy return, trả về là anh em hiểu là kết thúc một hàm. Có viết code vào đây thì cũng không chạy nữa. Câu lệnh này thường được sử dụng khi kết thúc một hàm

return 0;

Cuối cùng cũng xong, compile thành công nha anh em

Lập trình C++

3. Lưu ý

Bằng giải thích từng dòng code phía trên cho anh em mới bắt đầu bằng lập trình C++, có một số điểm anh em cần lưu ý .

  • Luôn luôn sử dụng include ở đầu file để thực thi các hàm dễ hàng hơn. Trong ví dụ này là <iostream>, nếu không có nó, câu lệnh trong hàm main như std::cinstd::cout sẽ không thể được gọi. Trình biên dịch sẽ báo lỗi
  • Thực thi của code luôn bắt đầu trong hàm main, bất kể là import thứ gì, không có hàm main() thì code sẽ không đươc thực thi.
  • It is a good practice to use Indentation and comments in programs for easy understanding.
  • cout is used to print statements and cin is used to take inputs.

Qua bài viết trên, bạn chắc hẳn cũng đã tích lũy được các kiến thức căn bản về lập trình C++. Cảm ơn anh em đã đọc bài – Thank you for your time. Happy coding!

TopDev tổng hợp và chỉnh sửa từ bài viết của tác giả Kiên Nguyễn

Xem thêm:

Tham khảo ngay việc làm IT mọi cấp độ trên TopDev!

 

Phép thử Turing – Bài kiểm tra trình độ AI dành cho máy tính

AI hay trí tuệ nhân tạo là 1 khái niệm không còn xa lạ ở thời đại hiện nay. Trong khoa học máy tính, AI được định nghĩa là trí thông minh mà được thể hiện bằng máy móc. Với AI, máy móc hiện nay có thể làm được rất nhiều thứ như con người, thậm chí nếu chỉ thông qua giao tiếp thông thường, bạn khó có thể xác định đối tượng bạn đang giao tiếp là người thật hay chỉ là 1 chiếc máy tính.

Vậy khi nào 1 máy tính được công nhận là sở hữu trí tuệ nhân tạo AI? Phép thử Turing (Turing Test) ra đời để trả lời cho vấn đề trên. Đây một phương pháp tìm hiểu về trí tuệ nhân tạo (AI) của máy tính, mục đích của nó là để xác định xem liệu một máy tính có khả năng suy nghĩ như con người không, hay nói cách khác Phép thử Turing là 1 bài kiểm tra trình độ AI dành cho máy tính. Trong bài viết này chúng ta cùng đi tìm hiểu về bài test này nhé.

Phép thử Turing là gì?

Phép thử Turing được đặt theo tên của nhà khoa học người Anh Alan Turing – người đã sáng lập ra phép thử này vào những năm 1950. Ông được 999xem như là cha đẻ của ngành khoa học máy tính và AI, nếu bạn muốn tìm hiểu thêm về ông thì có thể xem thêm phim “The Imitation Game” (Người giải mã) – một bộ phim kể về cuộc đời của ông và việc giải mã hệ thống điện báo của Đức Quốc xã trong chiến tranh thế giới thứ 2.

phép thử turingNguồn: Wikipedia

Mô hình chuẩn của phép thử Turing yêu cầu 3 thiết bị đầu cuối, mỗi thiết bị được tách biệt về mặt vật lý so với 2 thiết bị còn lại: trong đó 1 thiết bị được vận hành bởi máy tính, trong khi 2 thiết bị còn lại được vận hành bởi con người.

Như hình bên thì B và C sẽ con người, A là máy tính. C sẽ là “kẻ thẩm vấn” bằng cách thực hiện một cuộc thảo luận bằng ngôn ngữ tự nhiên với 2 “kẻ bị thẩm vấn” A và B, cả 2 đều cố gắng tỏ ra mình là con người. Nếu “kẻ thẩm vấn” C không thể nhận ra (hay phán đoán sai) A hay B là máy tính thì lúc đó máy tính A được xem là đã vượt qua phép thử về trí tuệ nhân tạo của nó. Điều này cũng đồng nghĩa với việc máy tính A được trang bị AI đã dần trở thành giống con người vì nó đã đánh lừa được con người thực sự.

Trong 1 khoảng thời gian dài sau đó, phép thử Turing trở thành động lực cơ bản trong lý thuyết và phát triển trí tuệ nhân tạo AI. Tiêu chuẩn đặt ra cho AI vào thời điểm đó là khả năng mô phỏng nhận thức và ra quyết định của con người. 

Khả năng kiểm tra trình độ AI của phép thử Turing

Vào thời điểm khi máy tính bắt đầu thể hiện được khả năng về “tư duy” và “trí tuệ” của mình thì việc định nghĩa trí tuệ nhân tạo gặp khó khăn và những câu hỏi liên quan đến việc đo lường khả năng tư duy của máy tính là điều bất khả thi. Phép thử Turing đã đưa ra cho chúng ta 1 cách thức để trả lời vấn đề trên cũng như 1 bài test để xác định xem máy tính có thực sự có trang bị AI hay không. AI – Trí tuệ nhân tạo ở trong phép thử Turing được hiểu 1 cách khá cơ bản: đấy là khả năng mô phỏng, bắt chước con người. Cũng chính vì sự đơn giản của mình mà phép thử Turing cũng mang khá nhiều nhược điểm và dần cho thấy sự lỗi thời của nó.

  • Yếu tố đầu tiên trong phép thử Turing là việc phản hồi lại những câu hỏi của người “thẩm vấn” một cách “con người nhất” khiến những câu hỏi trong phép thử Turing cần được hạn chế lại. Nói cách khác, máy tính muốn đạt được điểm cao trong bài test Turing thì cần có bộ câu hỏi trước có liên quan đến một lĩnh vực kiến thức hẹp nhất định, và nghiên cứu cho thấy bài test thích hợp sẽ chỉ bao gồm những câu hỏi có dạng Đúng hay sai (Yes/No questions).
  • Trong thực tế thì kết quả của thử nghiệm bị chi phối lớn do khả năng và thái độ của người hỏi. Có rất nhiều người với khả năng phán đoán của mình có thể dễ dàng nhận ra mình đang trò chuyện với 1 cái máy tính; nhưng ngược lại thì cũng có nhiều người rất khó để nhận ra sự khác biệt giữa 2 kẻ “bị thẩm vấn” ở đây.
  • Và điều quan trọng nhất mà khiến phép thử Turing không nhận được sự đồng tình cao trong quá trình phát triển của AI về sau này là tính hữu dụng của nó. Sự “thông minh” được đo lường qua phép thử Turing thể hiện bằng việc so sánh hành vi của máy tính và con người. Trong khi đó hiện nay như chúng ta đều biết, trọng tâm thực sự trong việc phát triển AI là làm thế nào để máy tính và con người tương tác với nhau hiệu quả, đem lại giá trị sử dụng tốt nhất cho con người. Nói đúng hơn thì máy tính không cần giống con người, miễn sao với trí tuệ của chúng có thể giúp đỡ con người 1 cách tốt nhất là được. 

Ứng dụng phép thử Turing hiện nay

Với những nhược điểm của mình thì hiện nay việc một máy tính có thể vượt qua được phép thử Turing hay không đã trở nên không mấy liên quan trong lĩnh vực AI. Tuy nhiên chúng ta cũng có thể bắt gặp nhiều phiên bản hay ứng dụng của nó đang được sử dụng rộng rãi hiện nay

  • CAPTCHA / reCAPTCHA

recaptcha

Nguồn: pvm.com.vn

Captcha hay reCaptcha là 1 hệ thống giúp phân biệt được truy cập từ người dùng hay từ những con bot. Có nhiều phương pháp được sử dụng như: nhập text, nhập kí tự trong hình ảnh, lựa chọn hình ảnh có nội dung, … Đây được xem là 1 ứng dụng của phép thử Turing, chỉ khác là lúc này người “thẩm vấn” lại chính là 1 hệ thống máy tính.

  • Chatbot

ứng dung turing trong chatbot

Nguồn: doopage.com

Chatbot cũng có thể được xem là 1 ứng dụng của phép thử Turing. Trong lĩnh vực tư vấn bán hàng, những người tạo ra chatbot mong muốn sự giống con người nhất, đem lại trải nghiệm tốt nhất dành cho khách hàng của mình. Và rõ ràng nếu chúng ta chat với chatbot mà vẫn cứ nghĩ có ai đó đang online ngày đêm trả lời, tận tình tư vấn sản phẩm cho mình thì con chatbot đó hẳn cũng đã vượt qua bài test Turing 1 cách xuất sắc.

Kết bài

Ngày nay khi mà AI đã tạo ra cho con người rất nhiều khái niệm mới, nhiều điều mà con người còn không nghĩ đến thì việc đánh giá trình độ AI bằng con người như phép thử Turing là một điều không có quá nhiều ý nghĩa. Tuy nhiên không thể phủ nhận được sự đóng góp của nó trong ngành khoa học máy tính trong việc đưa ra khái niệm và đo lường về trí tuệ nhân tạo. Cũng đã có nhiều phiên bản cập nhật của phép thử Turing được đưa ra nhưng điều đó thực sự không quá quan trọng, ý nghĩa lớn nhất của bài test này chính là việc nó đã mở ra nhiều cách cửa cho sự đổi mới trong lĩnh vực AI nói riêng cũng như công nghệ nói chung.

Hy vọng bài viết này mang lại được những kiến thức bổ ích cho các bạn, hẹn gặp lại các bạn trong các bài viết tiếp theo của mình.

Tác giả: Phạm Minh Khoa

Xem thêm:

IT job hot cho Top Developer, xem thêm tại TopDev!

Web3 techstack – Hành trang cho anh em developer

Web3 techstack

Ở bài viết trước, mình đã giới thiệu cho anh em về Web3 tại bài viết này (Anh em nào chưa có khái niệm hay cái nhìn đầu tiên về web3 có thể tham khảo nha), tiếp sau đây sẽ là Web3 techstack, hiểu khái niệm rồi giờ muốn bay vô làm luôn thì sao?

Muốn làm luôn thì trước tiên phải biết về Web3 techstack, ít nhất là biết nó sử dụng những gì, chức năng mỗi thằng ra sao chứ đúng không?

Bắt đầu luôn cho nóng,

1. À khoan, nhắc lại chút xíu

Về Web3 techstack chưa cần đi vội vàng chi cho vấp té, đầu tiên nhắc lại cho anh em là web3 xây dựng dựa trên hai thứ:

  • Đầu tiên là hệ sinh thái phi tập trung (Intdecentralized Internet Ecosystem).
  • Thứ hai là nền tảng blockchain.

Bắt đầu trên nền tảng là hai cái này, Web3 tuy phát triển nhanh nhưng cũng đã kịp xây dựng và củng cố dần cho mình cái khối block đằng sau nó.

Web3 techstack Nhắc tới web3 là nhắc tới blockchain và phi tập trung (decentralized)

Để hiểu rõ về Web3 techstack và về từng layer trong đó, anh em xem qua hình ảnh dưới đây

Web3 techstack layer

2. Web3 tech stack có gì?

Rồi, mỗi layer sẽ thực hiện một nhiệm vụ. Bắt đầu trước với Network layer

2.1 Web3 Network Layer

Rõ ràng là ứng dụng Web3 nào cũng cần xây dựng Network layer của riêng nó.

Web2 applications rely on centralized databases, Web3 applications are built on top of blockchain architectures for trustless and permissionless access. Những ứng dụng Web2 dựa trên những hệ cơ sở dữ liệu tập trung, ứng dụng Web3 thì lại xây dựng dựa trên kiến trúc blockchain để đảm bảo tính trustless và permission less

Chính vì base trên nền blockchain nên khi cần buid một ứng dụng phi tập trung – decentralized applications (dApps), anh em dev thường có hai lựa chọn:

  • Thứ nhất là Ethereum Virtual Machine (EVM), máy ảo Ethereum, loại này thì là blockchain tương thích
  • Thứ hai là không tương thích non EVM compatible blockchains

Web3 techstack

Nguồn ảnh: moralis.io

2.1.1 EVM – Ethereum Virtual Machine

Một số anh em tìm hiểu blockchain có lẽ không còn xa lạ với EVM, máy ảo EVM cho từng node sẽ là nơi lưu trữ thông tin quan trọng như tài khoản (accounts) hoặc số dư (balances).

Máy ảo của Ethereum cũng lưu trữ trạng thái máy, có thể thay đổi theo từng khối mới theo một bộ quy tắc được xác định trước do EVM đưa ra. Quan trọng nhất đối với các anh em dev là EVM cung cấp một khuôn khổ để lưu trữ và thực thi các hợp đồng thông minh (smart contracts), cho phép anh em lập trình tẹt ga các logic trên chuỗi.

Anh em start với EVM thì techstack có thể cân nhắc bao gồm:

  • Ethereum – EVM nguyên bản kèm với smart contract
  • Polygon – Ethereum sidechain
  • Arbitron – Layer 2 blockchain sử dụng Optimistic rollups và multi-round fraud proofs
  • Optimism – Layer 2 blockchain sử dụng Optimistic rollups và single-round fraud proofs
  • Hermez – ZK rollup Ethereum Layer 2 network quản lý bởi Polygon
  • ZKSync – ZK rollup Ethereum Layer 2 network sử dụng SNARKs
  • Starknet – ZK rollup Ethereum Layer 2 network sử dụng STARKs
  • Avalanche – EVM-compatible Layer 1
  • Cronos – EVM-compatible Layer 1

Web3 techstack Polygon trong gói giải pháp scaling có nhiều thứ hay ho như PoS, Supernets và Avail

Tham khảo các vị trí tuyển dụng Web developer cho bạn

2.1.2 Non EVM – Không tương thích

Có khuôn có khổ thì vẫn có ông đạp đổ cả khuôn. Gần đây có một số framework đã được xây dựng vượt ra sự bó buộc của EVM, cũng không tương thích với EVM.

Mấy ông này thì cho rằng chuỗi EVM quá bị ràng buộc bởi khuôn khổ Ethereum và thay vào đó mấy ổng chọn cách đổi mới bằng cách thiết kế các cấu trúc mới. Nói chung, các blockchains không phải EVM được thiết kế với dữ liệu và khả năng mở rộng giao dịch ngay từ đầu. Ngoài ra NonEVM còn cho phép giao dịch cao mỗi giây (TPS).

Một số Non EVM phổ biến hiện tại anh em có thể tham khảo nếu không muốn base trên nền của EVM. Việc lựa chọn EVM hay non EVM cho Web3 techstack đôi khi còn phụ thuộc vào tính năng ứng dụng anh em muốn build.

  • Flow – Layer 1 sử dụng Cadence, luồng là luồng hướng đối tượng resource-oriented programming language
  • NEAR – Layer 1 sử dụng Rust hoặc Assembly script cho cái smart contracts
  • Solana – Layer 1 sử dụng Rust C, C++ cho smart contracts
  • Terra – Layer 1 sử dụng Rust cho smart contracts

Luồng thanh toán của flow hỗ trợ nhiều cái tên đình đám như Coinbase và Binance. Nguồn ảnh: flow.com

2.2 Blockchain Interaction Layer

Sau khi đã có Network layer làm nền tảng cho blockchain thì lựa chọn thứ hai anh em cần ra quyết định là Interaction Layer.

Nghe cái tên thôi cũng đoán sơ sơ ra là nó để làm gì ha, Interaction là tương tác, có base blockchain sẵn có nếu sử dụng EVM rồi, giờ anh em cần read, write (đọc, ghi data) vào block chain thôi.

Mé sợ anh em không hiểu, đặc biệt là mấy anh em chưa biết về blockchain đành nhắc lại xíu.

  • Blockchain được xây dựng dựa trên các khối dữ liệu
  • Mỗi khối blocks này được phân tán trên các nodes và chúng độc lập với nhau.
  • Mỗi cái node này trong mạng blockchain lại cho phép ta đọc, ghi các khối dữ liệu
  • Quan trọng nhất là bất kỳ khối nào được thêm vào blockchain phải được truyền qua tất cả các nút trên mạng để được đồng bộ.

Với Interaction Layer, Web3 techstack mà anh em có thể chọn đầu tiên là Alchemy. Về cơ bản thì ông Alchemy này public một bộ API cho anh em giao tiếp đa lớp.

  • Layer 1s bao gồm Ethereum network
  • Layer 2s bao gồm Arbitrum và Optimism
  • Sidechains bao gồm Polygon, và non-EVM-compatible L1s như kiểu Flow.

Web3 techstack Alchemy – Platform cung cấp bộ Blockchain API thoải mái cho anh em sử dụng.

Ngoài ra, ông Alchemy này cho phép blockchain developer truy cập có thể mở rộng tới tất cả các lớp (Layer) trong Web3.

2.3 Web3 Presentation Layer

Thơm thơm, tới trình bày (Presentation) rồi nè

Theo nhiều cách, lớp trình bày Web3 phản ánh nhiều khía cạnh của sự phát triển Web2. Nói vậy là sao, ví dụ để tạo và phát triển các thành phần giao diện (UI) cho người dùng đi ha, nhiều frontend đã chuyển qua sử dụng Reactjs.

Với một số lượng lớn các nhà phát triển và một cộng đồng Web3 theo sau, đó là tiêu chuẩn thực tế cho phát triển UI của Web3. Đông đâu đó quyết định.

Tuy nhiên tầng presentation của Web3 có khác tí khi chọn techstack là nó cần tương tác với dữ liệu blockchain (nền là blockchain) mà.

Để tương tác với data, thay vì như ở web2 ta dùng Axios hay Fetch thì ở Web3 thường chọn đi với Ether.js hoặc Web3.js. Đặc biệt là cả Ether.js và Web3.js đều hỗ trợ remote procedure calls (RPC)

Ethers.js thì nhẹ hơn, thân thiện với mấy ông dev thì tài liệu nhiều. Có cái là mấy ông cộm cán phát triển Ether.js thì hình như nắm té cái quyền phát triển, do không là cộng đồng nên lực phát triển tiếp có hơi hạn chế.

Web3.js thì commit nhiều và là thư viện javascript Ethereum được sử dụng nhiều nhất. Mặc dù nó cũng được sử dụng rộng rãi, nhưng ông này nói thẳng là thiếu chiều rộng và chiều sâu. Đọc cực kỳ khó hiểu.

Web3 techstack Web3js nằm giữa, các user interface có thể đụng tới smart contract thông qua web3.js

Ngoài ra còn có thằng Alchemy Web3.js là Alchemy Web3, một bản fork với các phương thức API bổ sung, có hỗ trợ cả websocket và cho cộng đồng đóng góp.

Web3 techstack Web3js nay còn có cả Sturdier WebSockets. Nguồn ảnh: GeeksforGeeks

2.4 Web3 Application Layer

Phù, cuối cùng cũng tới Application Layer ha, lớp ứng dụng. Sau bao vất cả xây dựng và đống kiến thức khó nhai, khó hiểu của Web3 thì giờ Application Layer có thể dễ thở hơn cho việc anh em lựa chọn Web3 techstack.

Vậy tầng này làm gì?

Lớp ứng dụng (Application Layer) là thứ chủ yếu cho phép người tiêu dùng công cộng (nhiều ông trong số đó không cần phải hiểu hết sự phức tạp của phát triển Web3) dễ dàng tương tác với giao diện người dùng trực quan. Mà với cái trực quan này cơ, tức là bao gồm giao diện người dùng thân thiện thì con đem tới sức mạnh cho người dùng.

Nói chung web3 có dùng dễ hay không ăn thua ở lớp này.

Lớp này thì bao gồm nhiều thứ lắm. Đơn cử anh em biết tới DeFi, NFTs. Ngoài ra còn các mục khác như Identity & Authentication, Data & Analytics.

Đống này thì được phát triển bởi bộ ba công ty Web3 lớn và có tên tuổi như là:

  • OpenSea
  • Uniswap
  • Aave

Đối với anh em blockchain developer thì phần này có vẻ là hứng thú nhất. Ở đây thoải mái kết hợp vài ba cái ứng dụng phi tập trung (decentralized application) với nhau.

Web3 techstack Build lên như OpenSea sàn giao dịch NFT như này thì tầng Application Layer quyến rũ quá rồi.

Tác giả: Kiên Nguyễn

Xem thêm:

Xem tin tuyển dụng việc làm IT lương cao, đãi ngộ hấp dẫn tại đây!

Ứng dụng của phép toán Bitwise

ứng dụng của phép toán Bitwise

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

Trong chương trình giảng dạy IT của các trường đại học, cao đẳng hay trung tâm dạy nghề chúng ta đều được học các phép tính toán sau :

  • Số học (+,-*,/,%)
  • Logic (&&,|| )
  • Bitwise (&,|,~,^,>>,<<)

Trong khi phép toán Số học và Logic được ưng dụng rộng rãi trên hầu hết các hệ thống phần mềm cũng như bài tập trên trường lớp. Phép toán Bitwise có vẻ được ít các bạn lập trình viên quan tâm và rất ít người áp dụng được phép toán này trong các hệ thống phần mềm.

Bitwise là một phép toán cực quan trọng nếu nắm bắt được nó bạn có thể hiểu được một số tư tưởng của một số thuật toán tạo ID cũng như các opensource sử dụng nó. Áp dụng Bitwise vào trong hệ thống phần mêm của bạn sẽ giúp phần mềm của bạn trở lên tốt hơn cũng như giải quyết được nhiều bài toán khó.

Bài toán tạo ID

Ứng dụng hay được sử dụng nhất và cũng là ứng dụng nổi bật nhất của phép tính toán Bitwise là tạo một ID chứa nhiều thông tin bên trong.

Thông thường mọi người sẽ lưu ID dưới dạng số tăng dần vào các RDMS như : mysql, oracle , mariadb, postgresql ,… Sử dụng cơ chế auto increment hay sequence của các loại DB này để thực hiện tạo ID. Cách này sẽ làm tăng tải cho DB khi thực hiện insert dữ liệu. Kèm theo cách này thì thông tin của ID cung cấp cho chúng ta là không nhiều chỉ là đã tạo được bao nhiêu bản ghi nhưng nếu chúng ta xóa 1 row đi thì thông tin của ID mang lại hầu như không sử dụng được.

Trên thực tế với các phầm mềm mình đã làm và được nhận lại từ các chuyên gia thì họ thường sẽ không tạo ID kiểu vậy và sẽ sử dụng phép tính toán Bitwise để lưu thông tin.

Trong bài blog này mình sẽ lấy ví dụ và giải thích chi tiết thuật toán snowflake để các bạn có thể hiểu được tầm quan trọng của phép toán bitwise cũng như mình sẽ cung cấp một số common function để làm việc với bitwise. Hy vọng sau bài này các bạn sẽ luyện tập và tạo được ID theo ý và chứa nhiều thông tin hơn một số tự tăng.

Tạo ID theo thuật toán snowflake

Đối với các hệ thống phân tán ( distributed system ) việc tạo ID sao cho unique giữa các service cũng như ID chứa nhiều thông tin là một thách thức rất lớn nếu chúng ta không sử dụng phép Bitwise.

Thuật toán nổi tiếng nhất để tạo ID cho hệ thống này là snowflake. Bạn có thể tìm thấy rất nhiều implement trên mạng và tại blog này tôi cũng có 1 implement tại class IdGenerator trong project common cụ thể như sau:

package blog.common.id;

import java.time.Instant;
import java.util.Date;

public class IdGenerator {

    private static final int NODE_ID_BITS = 10;
    private static final int SEQUENCE_BITS = 12;

    private static final int maxSequence = (int) (Math.pow(2, SEQUENCE_BITS) - 1);

    private static final long CUSTOM_EPOCH = 1420070400000L;

    private long lastTimestamp = -1L;
    private long sequence = 0L;

    public static IdGenerator instance = new IdGenerator();

    public synchronized long nextId() {
        long id = nextId(188);
        return id;
    }


    private synchronized long nextId(int nodeId) {
        long currentTimestamp = timestamp();

        if (currentTimestamp < lastTimestamp) {
            throw new IllegalStateException("Invalid System Clock!");
        }

        if (currentTimestamp == lastTimestamp) {
            sequence = (sequence + 1) & maxSequence;
            if (sequence == 0) {
                // Sequence Exhausted, wait till next millisecond.
                currentTimestamp = waitNextMillis(currentTimestamp);
            }
        } else {
            // reset sequence to start with zero for the next millisecond
            sequence = 0;
        }

        lastTimestamp = currentTimestamp;

        long id = currentTimestamp << (NODE_ID_BITS + SEQUENCE_BITS);

        id |= (nodeId << SEQUENCE_BITS);
        id |= sequence;
        return id;
    }


    private static long timestamp() {
        return Instant.now().toEpochMilli() - CUSTOM_EPOCH;
    }

    private long waitNextMillis(long currentTimestamp) {
        while (currentTimestamp == lastTimestamp) {
            currentTimestamp = timestamp();
        }
        return currentTimestamp;
    }

    public short getNodeIdById(long id) {
        return (short) ((id >> SEQUENCE_BITS) & 0x2ff);
    }

    public long getTimestampById(long id) {
        return (id >> 22) + CUSTOM_EPOCH;
    }
}

Nếu bạn không hiểu nhiều về phép bitwise thì bạn có thể không hiểu lý do tại sao cách tạo ID theo thuật toán snowflake sẽ cho chúng ta các ID khác nhau trên một hệ thống phân tán. Và các thông tin chứa trong ID đó là gì. Chúng ta sẽ phân tích snowflake bằng cách implement trong bài blog này.

Khi tạo ID theo implement thì trong ID sẽ chứa các thông tin sau:

  • Thời gian ID đó được tạo ra
  • Node nào tạo ra ID đó theo NodeID
  • sequence: thứ tự ID được tạo trong một milliseconds nếu có nhiều ID được tạo trong cùng thời gian. Thông tin này không quá quan trọng với logic sau này.

Cách kết hợp 3 thông tin trong cùng ID

Như chúng ta biêt số long trong java sẽ la 8 bytes và là 64 bits. Việc cần làm ở đây là quy định các thông tin chứa trong ID sẽ chiếm bao nhiêu bits và sẽ nàm ở vị trí nào trong 64 bits này, vì bit đầu là bit dấu nên chúng ta chỉ dùng được 63 bits. Với cách implement trên thì chúng ta sắp xếp như sau:

  • Thời gian tạo ID : 41 bits đầu tiên Với 41 bits này thì chúng ta có thể tạo ID trong khoảng 69 năm tính từ thời điểm CUSTOM_EPOCH. Bởi vì nếu vượt qua 69 năm thì Instant.now().toEpochMilli() - CUSTOM_EPOCH; sẽ vượt qua 41 bits khiến cho ID tạo ra không còn đảm bảo đúng được nữa.
  • Định danh service tạo ID (nodeId) : 10 bits. Có thể chứa tới 1024 định danh của các service khác nhau. Mình chưa bao giờ thấy service nào có nhiều instance đến thế.
  • Số tăng dần sequence : 12 bit . sẽ tạo ra 4096 ID khác nhau trong một millisecond. Nếu thời gian gọi tạo ID của service là trùng nhau ở mức millisecond thì sequence sẽ có tác dụng tạo ra các ID tăng dần khác nhau.

Ví dụ

Lý thuyết là thế sau đây mình sẽ làm một ví dụ cho các bạn hiểu thêm về cách hoạt động của snowflake.

Thời điểm mình tạo ID tính theo millisecond sẽ là 1649991105180L sau khi trừ đi CUSTOM_EPOCH sẽ được số 229920705180. Đổi số này thành dạng nhị phân dưới dạng long ta sẽ được số 00000000 00000000 00000000 00110101 10001000 01010111 10001010 10011100

Sau khi dịch sang trái 22 bit thì ta sẽ được số dạng nhị phân sau: 00001101 01100010 00010101 11100010 10100111 00000000 00000000 00000000

Mình đang hard code NodeID là : 18, đổi số này sang sạng binary long sẽ được số sau : 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00010010

Dịch sang trái 10 bit ta được số sau : 00000000 00000000 00000000 00000000 00000000 00000000 01001000 00000000

Sequence đang là “0” ta sẽ được số sau : 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

ta thực hiện phép toán | để gộp 3 số sau thành 1 số long mới ta được

 00001101 01100010 00010101 11100010 10100111 00000000 00000000 00000000
|
 00000000 00000000 00000000 00000000 00000000 00000000 01001000 00000000
|
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
-----------------------------------
 00001101 01100010 00010101 11100010 10100111 00000000 01001000 00000000

Đổi ra số dạng decimal được : 964357333419313152

Tìm việc làm Java mọi cấp độ tại đây!

Lấy các thông tin được lưu trong ID ra

Ta chỉ cần làm các động tác ép kiểu và bitwise ngược lại thì sẽ lấy ra được thông tin như thời gian tạo IDservice nào tạo ID. Trong code Demo bên trên mình đã code sẵn các hàm giúp các bạn lấy ra thông tin này.

    public short getNodeIdById(long id) {
        return (short) ((id >> SEQUENCE_BITS) & 0x2ff);
    }

    public long getTimestampById(long id) {
        return (id >> 22) + CUSTOM_EPOCH;
    }

Phần giải thích tại sao lại lấy ra thông tin bằng các hàm này mình sẽ nhường các bạn để hiểu hơn về cách hoạt động của bitwise sau này có thể tùy chỉnh thuật toán snowflake theo ý.

Việc lấy ra các thông tin này cung cấp cho chúng ta khả năng thực hiện các validate dữ liệu mà không cần phải vào Database lấy các thông tin này ra. Trên thực tế nếu tạo ID kiểu này mình thường lấy thời gian ra để thực hiện một số nghiệp vụ validate timeout,…

Tự tạo thuật toán sinh ID

Việc nắm rõ cách hoạt động của một số bitwise cơ bản như (<<,>>,|,&) sẽ giúp các bạn không chỉ tạo ID theo thuật toán snowflake mà giúp các bạn tạo ra các loại ID có nhiều thông tin theo ý muốn của bạn. Ví dụ bạn muốn tạo một customerID chứa thông tin của quốc gia của customer đó thì bạn có thể tạo một customerID dạng integer với 9 bits đầu để lưu mã quốc gia (vì một bit đầu tiên là bit dấu mà có hơn 200 quốc gia trên toàn thể giới) và 23 bit sau thì lưu sequence.

    public static int generateCustomerId(short nationalId, int sequence) {
        int id = ((int) (nationalId & 0x1ff)) << 23;
        id |= sequence & 0x007FFFFF;
        return id;
    }

    public static short getNationalId(int customerId) {
        short id = (short) ((short) (customerId >> 23) & 0x1ff);
        return id;
    }

Một số ứng dụng khác khi dùng bitwise

Các ứng dụng này sẽ là các cải thiện về hiệu năng của chương trình khi chạy nhưng nó chỉ cải thiện rất nhỏ vì các cách khác cũng đủ nhanh rồi.

Số chắn số lẻ

// Returns true if n is even, else odd
static boolean isEven(int n)
{
    // n&1 is 1, then odd, else even
    return ((n & 1)!=1);
}

   // Returns true if n is even, else odd
    static boolean isEven1(int n)
    {

        // n^1 is n+1, then even, else odd
        if ((n ^ 1) == n + 1)
            return true;
        else
            return false;
    }

Binary serialize Một ứng dụng tuyệt vời khác của bitwise là dùng để serialize dữ liệu thành array byte sau đó được ghi vào các file nhị phân (các loại database đều dùng binary file), hoặc truyền các array byte này thông qua mạng đến các service. Vì đọc file nhị phân hay deserialize array byte sẽ nhanh hơn và tiết kiệm tài nguyên hơn rất nhiều so với json nên nó nâng cao tốc độ của service của bạn.

Các thư viện giúp bạn làm điều này như : proto, thrift, kryo,… Hoặc các bạn cũng có thể tự tạo cho mình một cách serialize dữ liệu bằng cách sử dụng bitwise và nên tuân theo cách big-endian (BE) or little-endian (LE). Mình cũng đã từng chia sẻ sơ qua về cách này tại blog How to serialize data in java like protobuf. Nếu các bạn quan tâm thì vào đọc ủng hộ giúp mình nhé.

Đây là cách mình dùng bitwise để serialize một số int thành 1-5 bytes thay vì 4 bytes.

default void writeIntOptimise(int value) {
        if ((value < 0)) throw new IllegalArgumentException("pack int: " + value);
        int x;
        while (true) {
            x = value & 0x7F;
            value >>>= 7;
            if (value != 0) {
                this.writeByte((byte) (x | 0x80));
            } else {
                this.writeByte((byte) x);
                break;
            }
        }
    }

Chi tiết các bạn tham khảo code phần serilize này tại link github

Bitwise number common fuction

Tại hệ thống mình làm khi giao tiếp với phần mềm bên thứ 3 họ chỉ chấp nhận số lớn nhất là int nhưng ID của hệ thống mình là một số long vậy nên bọn mình đã sử dụng bitwise để tách 1 số long thành 2 số int và khi nhận về 2 số int sẽ ghép thành 1 số long để 2 hệ thống kết hợp với nhau tốt hơn. Do đó mình xin chia sẻ cho anh em các hàm common chuyên sử dụng để tách các số như vậy.

package blog.common.id;

public class Numbers {

    // phan tach so long thanh int va nguoc lai
    public static final long toLong(final int v1, final int v2) {
        return (((long)v1 << 32) & 0xFFFFFFFF00000000L) | ((long)v2 & 0x00000000FFFFFFFFL);
    }

    public static int lowInt(long value) {
        return (int)(value & 0xFFFFFFFFL);
    }

    public static int highInt(final long value) {
        return (int)((value >>> 32) & 0xFFFFFFFFL);
    }


    // phan tach so int thanh short va nguoc lai
    public static final int toInt( short v1, short v2 ) {
        return ((v1 << 16) & 0xFFFF0000) | (v2 & 0x0000FFFF);
    }

    public static short lowShort(int value) {
        return (short)(value & 0xFFFF);
    }

    public static short highShort(final int value) {
        return (short)((value >>> 16) & 0xFFFF);
    }


    // phan tach so short thanh byte va nguoc lai
    public static final short toShort(byte v1, byte v2) {
        return (short)(((v1 << 8) & 0xFF00) | (v2 & 0x00FF));
    }

    public static byte lowByte(short value) {
        return (byte)(value & 0xFF);
    }

    public static byte highByte(short value) {
        return (byte)((value >>> 8) & 0xFF);
    }
}

Tổng kết

Nắm vững kỹ thuật bitwise này sẽ giúp ứng dụng của bạn trở lên thông minh hơn. ID sẽ trở lên có ý nghĩa hơn. Trong bài mình sử dụng java để thực hiện viết demo thuật toán cũng như common nhưng bitwise sẽ sử dụng trong tất cả các ngôn ngữ lập trình. Hiện tại mình đang học và lập trình ngôn ngữ C++ và vẫn áp dụng phép tính toán này bình thường. Hy vọng sau khi làm quen với C++ thì mình sẽ có một số bài blog chia sẻ về ngôn ngữ này.

Nếu bài viết này hay thì mình xin một sao github cho có động lực update thêm bài tiếp theo nhé.

Link GitHub xin sao: github.com/trandem/blog/blob/main/common/bi..

Bài viết gốc được đăng tải tại demtv.hashnode.dev

Xem thêm:

Tham khảo hàng loạt tin tuyển dụng IT hấp dẫn tại TopDev

Giới thiệu về Enterprise Service Bus

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

Enterprise Service Bus (ESB) là thành phần trọng tâm trong một hệ thống phân tán, giúp kết nối các thành phần, các ứng dụng khác nhau lại với nhau. Vậy cụ thể nó là gì, trong bài viết này chúng ta hãy cùng tìm hiểu nhé các bạn!

Tại sao lại cần phải có ESB?

Hãy tưởng tượng các bạn đang làm việc trong một hệ thống có nhiều ứng dụng và các ứng dụng đó cần được liên kết, trao đổi thông tin với nhau: ứng dụng A cần gửi một message tới ứng dụng B thông qua JMS, ứng dụng C cần gọi tới ứng dụng D để lấy thông tin cần thiết thông qua giao thức HTTP, … Tất cả các nhu cầu này được thực hiện dưới nhiều hình thức khác nhau, không cùng chung một định dạng các kiểu dữ liệu hay cùng một chuẩn giao tiếp chung.

Lập trình viên cho các ứng dụng này cũng đối mặt với nhiều khó khăn về mặt:

  • Giao thức: các ứng dụng này phải làm việc với các dữ liệu đầu vào từ các tập tin hệ thống cho tới các API RESTful web service.
  • Định dạng dữ liệu: các ứng dụng có thể sử dụng bất kỳ định dạng dữ liệu nào để trao đổi với nhau.
  • Cách trao đổi dữ liệu: các ứng dụng có thể gọi đến ứng dụng khác theo kiểu đồng bộ, bất đồng bộ, messaging, … rất nhiều cách trao đổi dữ liệu khác nhau.
  • Vòng đời của một ứng dụng: các ứng dụng khác nhau sẽ cần phải phát triển, bảo trì và quản lý theo những cách khác nhau.
  • Xử lý lỗi: đây là vấn đề cốt lõi của các ứng dụng, mỗi ứng dụng khác nhau sẽ có cách xử lý lỗi khác nhau.
  • Giám sát: việc giám sát việc tích hợp giữa các ứng dụng cũng gây nhiều khó khăn cho các lập trình viên.

Một vấn đề nữa là các ứng dụng phải kết nối trực tiếp với nhau theo kiểu một-một, gây khó khăn cho việc mở rộng sau này khi số lượng kết nối ngày một tăng lên.

Enterprise Service Bus (ESB) là gì?

Để giải quyết vấn đề này, một hệ thống Enterprise Service Bus đã được giới thiệu. Chúng ta sẽ tìm hiểu kỹ hơn về nó trong phần tiếp theo nhé các bạn!

Tìm việc làm Java lương cao, đãi ngộ hấp dẫn tại đây!

Enterprise Service Bus là gì?

ESB là một giải pháp cho vấn đề kết nối một-một trong một hệ thống có nhiều ứng dụng kết nối với nhau. Nó định nghĩa một nơi để các ứng dụng có thể thông qua nơi này tương tác với các ứng dụng khác, gọi là bus. Tất cả các ứng dụng của hệ thống bây giờ sẽ chỉ nói chuyện với nhau thông qua bus.

Hãy xem hình vẽ sau để hình dung rõ hơn ý nghĩa của ESB nhé các bạn:

Enterprise Service Bus (ESB) là gì?

Để làm được điều này, hệ thống bus của chúng ta phải có thể giao tiếp thông qua nhiều giao thức khác nhau như HTTP, FTP, … và nó phải sử dụng một chuẩn định dạng dữ liệu chung cho tất cả các message như Java object hay XML.

ESB cho phép chúng ta gom tất cả các vấn đề về bảo mật, chuyển hướng và chuyển đổi dữ liệu về một chỗ. Việc chuyển đổi từ service này sang service khác cũng diễn ra suôn sẻ mà không cần phải thay đổi gì ở các ứng dụng kết nối.

Xem thêm https://en.wikipedia.org/wiki/Enterprise_service_bus

Các framework hiện thực Enterprise Service Bus

  • Mule Enterprise Service Bus
  • Apache ServiceMix
Bài viết gốc được đăng tải tại huongdanjava.com
Xem thêm:

Đừng bỏ lỡ việc làm IT mọi cấp độ tại TopDev!

Tạo Input AutoComplete đơn giản với CSS trong React

tạo Input AutoComplete với CSS trong React

AutoComplete là một tính năng giúp bạn có thể đưa ra các gợi ý thông qua các kí tự mà người dùng nhập vào trong ô input. Nó thừa được sử dụng với form để giảm bớt thời gian nhập liệu cũng như tăng trải nghiệm người dùng khi sử dụng website của bạn. Hầu hết các thư viện UI Components hiện nay đều cung cấp sẵn cho bạn Input AutoComplete component; trong bài viết này mình sẽ hướng dẫn các bạn tạo 1 component đơn giản như thế chỉ với code React và sử dụng CSS.

Autocomplete Field

Nguồn ảnh: queryscript.net

Phân tích yêu cầu

Như hình trên, chúng ta có thể thấy Autocomplete Field bao gồm 2 phần: Input nhập giá trị và List danh sách các gợi ý hiển thị lên. Các yêu cầu đáp ứng như sau:

  • Khi người dùng bấm vào ô input (focus) thì sẽ hiển thị ra danh sách dropdown list gợi ý
  • Khi người dùng bắt đầu gõ vào ô input giá trị, chúng ta sẽ get lấy giá trị nhập vào, sau đó thực hiện tìm kiếm trong danh sách gợi ý những giá trị có chứa kí tự nhập vào đó. Khi lọc xong gợi ý sẽ hiện thị lên lại cho người dùng lựa chọn
  • Khi người dùng bấm 1 lựa chọn trong danh sách gợi ý sẽ thực hiện ẩn danh sách gợi ý đi, set lại giá trị ô input là giá trị mà người dùng vừa chọn

Đã làm rõ được yêu cầu, chúng ta cùng thực hiện code component này nhé. 

Bước đầu tiên chúng ta sẽ tạo ra 2 biến state là value và show

  • Biến value dạng string sẽ lưu giá trị mà người dùng nhập vào ô input để thực hiện search  
  • Biến show dạng bool sẽ làm nhiệm vụ set trạng thái ẩn hiện của dropdown danh sách các gợi ý lựa chọn
const [value, setValue] = React.useState("");
const [show, setShow] = React.useState(false);

Tạo ô Input text cho người dùng tương tác tìm kiếm

Chúng ta sử dụng thẻ input có sẵn, value được lấy giá trị state tạo ở bước trên. Khi người dùng focus vào ô input thì sẽ hiển thị dropdown list những gợi ý. Để làm được điều này chúng ta sử dụng thuộc tính onFocus, trong đó sẽ set giá trị biến state show thành true.

<input
     onFocus={() => setShow(true)}
     onBlur={() =>
       setTimeout(() => {
         setShow(false);
          }, 150)
       }
     value={value}
     onChange={onInputChange}>
</input>

Hàm onChange được gọi đến mỗi lần người dùng thay đổi giá trị của ô input, lúc đó chúng ta sẽ xử lý set lại giá trị cho biến state value

const onInputChange = (event) => {
    const value = event.currentTarget.value;
    setValue(() => value);
  };

Hàm onBlur được gọi đến khi người dùng chọn 1 lựa chọn trên dropdown list, lúc đó chúng ta sẽ xử lý ẩn dropdown list gợi ý đi. 

Tiếp theo chúng ta tạo 1 component list để hiển thị những lựa chọn gợi ý

Mỗi line được tạo bởi button để có thể tương tác bấm chọn. Logic xử lý ở đây như sau: Khi người dùng nhập giá trị vào ô input text

const ItemList = (() => {
    if (!show) return [];
    return list
      .filter((v) => v.toLowerCase().includes(value.toLowerCase()))
      .map((v) => (
        <button
          onClick={() => {
            setValue(() => v);
            setShow(false);
          }}
          key={v}
        >
          {v}
        </button>
      ));
  })();

CSS lại cho component của mình

  • Style dành cho ô input 
.container > div input {
  width: 100%;
  height: 40px;
  border: 1px solid #ccc;
  border-radius: 5px;
  font-size: 16px;
}
.container > div input:focus {
  outline: 1px solid rgb(83, 172, 255);
}
  • Style cho dropdown list gợi ý
.list {
  display: flex;
  flex-direction: column;
  max-height: 220px;
  width: inherit;
  overflow: auto;
  overflow-x: hidden;
  box-shadow: rgba(0, 0, 0, 0.12) 0px 1px 3px, rgba(0, 0, 0, 0.24) 0px 1px 2px;
}
 .list button {
  background: none;
  border: none;
  width: 100%;
  height: 100%;
  max-height: 3em;
  padding: 10px;
  text-align: left;
  cursor: pointer;
  border-bottom: 1px solid #ccc;
}
 .list button:hover {
  background: #f8f8f8;
}
 .list button:last-child {
  border-bottom: none;
}

Thành quả cho component AutoComplete của chúng ta

Input AutoComplete component

Các bạn có thể tham khảo full source code của component ở link dưới đây:

https://codepen.io/phm-minh-khoa/pen/dymQvMm

Trong ví dụ này mình sử dụng input autocomplete cho việc đưa ra gợi ý lựa chọn tỉnh thành phố Việt Nam. Khi người dùng nhập từ “hà”, component sẽ hiển thị ra dropdown list gợi ý bao gồm 4 lựa tỉnh và thành phố: “Hà Nội, Hà Giag, Hà Nam, Hà Tĩnh“ tương ứng.

Kết bài

Như vậy chỉ bằng JS và CSS đơn giản chúng ta đã tạo ra được 1 component Input AutoComplete để sử dụng trong React (hay bất cứ thư viện nào viết bằng JS). Trong React, các bạn có thể tạo thành 1 Input AutoComplete component chung để có thể tái sử dụng một cách dễ dàng, ngoài ra có thể sử dụng thêm các props khác truyền từ component cha vào để có thể tương tác với component và sử dụng nó trong form 1 cách hiệu quả hơn. Các components khác tương tự các bạn cũng hoàn toàn có thể tạo ra tương tự mà không cần sử dụng 1 thư viện UI Components ngoài nào khác.

Cảm ơn các bạn đã theo dõi và đọc bài, hy vọng bài viết hữu ích dành cho bạn, hẹn gặp lại trong các bài viết tiếp theo của mình.

Tác giả: Phạm Minh Khoa

Xem thêm:

Tham khảo việc làm IT mọi cấp độ tên TopDev

One Mount mở “sàn đấu Hackathon” cho hàng nghìn Kỹ sư lập trình

one mount mở cuộc thi hackathon

Tập đoàn One Mount mở sân chơi lập trình <One Mount Hack2Hire> quy mô toàn quốc, giúp Lập trình viên không chỉ được “bão não” với các bài toán công nghệ, mà còn được “bổ não” qua phiên chia sẻ chuyên sâu và tạo các kết nối mới với cộng đồng kỹ sư chung đam mê. 

Hackathon

One Mount Hack2Hire là cuộc thi Hackathon dành cho kỹ sư đam mê lập trình – những người không ngừng tìm kiếm cơ hội để định vị năng lực và sẵn sàng kết nối để phát triển bản thân tốt hơn mỗi ngày. 

Hiện thực hóa ý tưởng thay đổi cách tiếp cận và phương pháp đánh giá tiềm năng ứng viên công nghệ qua phỏng vấn Hỏi – Đáp truyền thống; Tập đoàn One Mount đầu tư xây dựng sân chơi “thực chiến” nhằm đánh giá toàn diện tư duy phát triển phần mềm, sức sáng tạo trong công nghệ và khả năng giải quyết vấn đề của các kỹ sư trong ngành IT.

“One Mount không muốn giới hạn ứng viên trong phạm vi phỏng vấn hay bài thi truyền thống. Thay vào đó, chúng tôi đưa ra các đầu bài mở, có tính thực tế cao để các bạn thể hiện năng lực theo suy nghĩ và phương pháp của bản thân tại một sân chơi thực sự “geek”, thực sự công nghệ.” – Anh Đinh Việt Hưng – Giám đốc Công nghệ và Dữ liệu Tập đoàn One Mount chia sẻ. 

Anh Đinh Việt Hưng - Giám đốc Công nghệ và Dữ liệu Tập đoàn One Mount

Anh Đinh Việt Hưng – Giám đốc Công nghệ và Dữ liệu Tập đoàn One Mount

Cuộc thi <One Mount Hack2Hire> mở “sàn đấu” cho nhóm Sinh viên công nghệ năm 4 và Kỹ sư dưới 5 năm kinh nghiệm với tổng giải thưởng lên tới 500.000.000 VND, cùng nhiều quà tặng công nghệ như Ipad, đồng hồ thông minh,…từ các đối tác đồng hành lớn như Google Cloud, Confluent, New Relic, CloudFlare, Kong…Người tham gia được lựa chọn công nghệ sở trường như Back-End (Java/Golang), Front-end (ReactJS, AngularJS), Mobile (iOS, Android và Flutter). 

hackathon gift

“Đặc thù “dân tech” thường hướng nội, khó thể hiện hết khả năng trong quá trình phỏng vấn. Được lựa chọn công nghệ sở trường yêu thích để thi đấu sẽ giúp các bạn thực sự tỏa sáng và thể thể hiện tối đa năng lực bản thân.” CIO One Mount, Anh Đinh Việt Hưng cho biết. 

Vòng chung kết – Offline Hacking Day dự kiến được tổ chức vào ngày 10/09 tại Hà Nội – là sự kiện đáng mong chờ nhất với kỹ sư mê lập trình sau 2 năm vắng bóng các cuộc tranh tài. Tại vòng chung kết, người tham gia không chỉ được “bão não” với các bài toán công nghệ, mà còn được “bổ não” qua phiên chia sẻ chuyên sâu và tạo các kết nối mới với cộng đồng Kỹ sư chung đam mê. 

kỹ sư tham gia hackathon

Cuộc thi <One Mount Hack2Hire> là sự kiện đầu tiên tại Việt Nam kết hợp giữa hoạt động Hackathon và Tuyển dụng nhân sự. Bên cạnh tạo cơ hội để kỹ sư định vị năng lực trong ngành IT, One Mount đặt mục tiêu tuyển dụng 20 nhân sự có tư duy phát triển sản phẩm nổi bật tham gia xây dựng các sản phẩm phục vụ hàng triệu người dùng tại Việt Nam. 

Là nơi quy tụ gần 2.000 nhân sự với chế độ đãi ngộ hấp dẫn và cơ hội bứt tốc sự nghiệp nhanh chóng, One Mount được vinh danh là Môi trường làm việc hấp dẫn Châu Á và là nơi nhiều nhân tài trẻ ưu tiên lựa chọn gắn bó, phát triển bản thân.

Tìm hiểu chi tiết Cuộc thi <One Mount Hack2Hire> tại: hack2hire.onemount.com

Tìm việc làm IT mọi cấp độ tại TopDev

Khi nào nên sử dụng useMemo và useCallback trong React?

Khi nào nên sử dụng useMemo và useCallback trong React?

Tác giả: Phạm Minh Khoa

React cung cấp cho chúng ta 2 hooks là useMemo và useCallback, chúng rất hữu ích khi bạn xử lý với những hoạt động phức tạp, tốn nhiều thời gian và tài nguyên của ứng dụng.

Nếu trong React component của bạn có chứa những hoạt động tốn tài nguyên (expensive operation), mỗi lần component được renders lại thì những tasks đó cũng sẽ được chạy lại khiến cho ứng dụng của bạn trở nên chậm chạp hơn. 2 hooks trên sẽ giúp tối ưu (optimize) ứng dụng của bạn bằng cách chạy những hoạt động tốn tài nguyên đó và lưu trữ kết quả (store result) của chúng lại trong cache. Khi component render lại trong lần tiếp theo thì chúng sẽ được chạy lại các hoạt động đó mà thay vào đó sẽ trả về luôn kết quả từ trong cache.

useMemo hoạt động thế nào?

Giả sử rằng chúng ta có 1 đoạn code xử lý hoạt động tốn thời gian và tài nguyên trong React component như sau:

function uselessExpensiveOperation(input) {
    const someBigArray = [];
    for (let i = 0; i < 5_000_000; i++) {
        someBigArray.push(input * i);
    }
    return someBigArray;
}

function SomeReactComponent() {
    const expensiveOperationResult = uselessExpensiveOperation(3);
    const output = expensiveOperationResult
        .slice(0, 5)
        .map(number => <li key={ number }>{ number }</li>);

    return <ul>{ output }</ul>;
}

function này sẽ chạy mất khoảng vài giây, nó sẽ trả về 1 mảng 5 triệu giá trị số phụ thuộc vào tham số đầu vào. Nếu bạn sử dụng hàm uselessExpensiveOperation trực tiếp trong 1 component React thì mỗi lần gọi xử lý render, nó sẽ gọi và chạy lại.

Trường hợp này chúng ta dùng useMemo để lưu trữ giá trị trả về trong cache như sau:

function SomeReactComponent() {
    const expensiveOperationResult = useMemo(
        function() {
            return uselessExpensiveOperation(3);
        },
        []
    );
    const output = expensiveOperationResult
        .slice(0, 5)
        .map(number => <li key={ number }>{ number }</li>);

    return <ul>{ output }</ul>;
}

useMemo nhận tham số đầu tiên là 1 function chứa hoạt động xử lý tốn tài nguyên (expensive operation), biến số thứ 2 là 1 mảng các phụ thuộc (dependencies). Nếu có sự thay đổi giá trị của bất cứ phụ thuộc nào thì React sẽ thực hiện việc xóa cache và chạy lại task tốn tài nguyên trên.

  useMemo là gì? Hướng dẫn sử dụng React useMemo Hook
  React hook là gì và lợi ích mà React hook đem lại

Ý tưởng của mảng các phụ thuộc là những gì mà bạn cần thêm vào như các biến mà hoạt động tốn tài nguyên ấy cần để xử lý. Như trong ví dụ trên thì hoạt động tốn tài nguyên của chúng ta không cần bất cứ phụ thuộc nào nên mảng truyền vào để rỗng (empty array).

useCallback hook sử dụng như thế nào?

useCallback khá giống với useMemo nên khiến các bạn có thể dễ nhầm lẫn; điều khác biệt là nó lưu trữ các functions (hàm) trong cache thay vì lưu trữ kết quả (results).

function SomeReactComponent() {
    const cachedFunction = useCallback(
        function originalFunction() {
            return "some value";
        },
        []
    );

    return <div>{ cachedFunction() }</div>
}

useMemo cũng làm được như useCallback nhờ việc React cung cấp 1 function đặc biệt là React.memo, nó hoạt động giống như useMemo nhưng nó lưu trữ React components vào trong cache để tránh việc render lại không cần thiết. Nó hoạt động như sau:

const cachedComponent = React.memo(
    function SomeReactComponent(props) {
        return <div>Hello, { props.firstName }!</div>
    }
);

Component SomeReactComponent sẽ được lưu trữ trong cache cho đến khi 1 trong những props thay đổi, lúc đó nó sẽ được render lại và lưu trữ vào cache 1 lần nữa.

Tuy nhiên có 1 vấn đề ở đây mà bạn cần lưu ý: Nếu trong props có chứa 1 function mà nó được tạo ra trong component cha (parent components), lúc đó mỗi khi component cha render lại thì function đó (inner function) cũng sẽ được tạo lại, điều đó khiến cho nó được xem là 1 function khác trong khi code không hề thay đổi. Dẫn đến việc nó sẽ khiến components đã cached sẽ bị render lại không cần thiết.

Lúc này nếu bạn sử dụng hook useCallback thì vấn đề trên sẽ có thể được giải quyết. useCallback sẽ chỉ tạo function trong lần đầu tiên component được render. Khi component được render lại thì nó sẽ lấy function đó từ trong cache, và trả về đúng function cũ, điều đó giúp cho props sẽ không bị thay đổi và phải render lại không cần thiết.

Đừng tối ưu quá mức (Over Optimize)

Có nhiều bạn dev sử dụng 2 hooks trên (hoặc 1 vài kĩ thuật optimize khác) ngay cả khi chúng không cần thiết. Các bạn lưu ý mục đích của 2 hooks này sinh ra, bài toán nó giải quyết, trường hợp nó nên được sử dụng. Nó có thể khiến cho code của bạn trở lên phức tạp hơn, khó maintain hơn và trong 1 vài trường hợp thậm chí nó còn hoạt động tồi hơn.

Bạn hãy nên áp dụng những kĩ thuật tối ưu hiệu năng sau khi phát hiện ra vấn đề, khi 1 thứ gì đó không chạy nhanh như bạn mong muốn thì hãy tìm hiểu xem nút thắt cổ chai (bottleneck) nằm ở đâu và tối ưu hóa phần đó.

Cảm ơn các bạn đã đọc.

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

Xem thêm:

Tham khảo ngay Top IT job hot có tại TopDev!

Lập trình Swift: Lười là thông minh!

Lập trình Swift: Lười là thông minh!

Tác giả: Lê Xuân Quỳnh

Nghe hơi vô lý nhưng rõ ràng Apple đã tạo điều kiện để Developer lười theo cách thông minh của họ.

Chúng ta sẽ tìm hiểu vì sao nói lười là thông minh? Nghe hư cấu nhỉ? 🤣

Nào cùng bắt đầu tìm hiểu về lười = lazy!

Mảng lười

Mở bài hơi sốc 1 xíu thôi, cùng theo dõi đoạn code sau nhé:

var numbers: [Int] = [1, 2, 3, 6, 9]
let modifiedNumbers = numbers
.filter { number in
print("Even number filter")
return number % 2 == 0
}.map { number -> Int in
print("Doubling the number")
return number * 2
}
print(modifiedNumbers)

/*
kết quả:
Even number filter
Even number filter
Even number filter
Even number filter
Even number filter
Doubling the number
Doubling the number
[4, 12]
*/

Như các bạn thấy, đầu tiên chúng ta tạo 1 mảng số nguyên. Sau đó dùng hàm filter để tìm ra các số chẵn(chúng ta có 2, 6). Tiếp theo chúng ta dùng hàm map để nhân đôi các số sau khi filter.

Kết quả chúng ta có 4, 12.

Bây giờ chúng ta sẽ dùng lazy như nào? Hãy theo dõi đoạn code sau:

let modifiedLazyNumbers = numbers.lazy
.filter { number in
print("Lazy Even number filter")
return number % 2 == 0
}.map { number -> Int in
print("Lazy Doubling the number")
return number * 2
}
print(modifiedLazyNumbers)
// Prints:
// LazyMapSequence>, Int>(_base: Swift.LazyFilterSequence>(_base: [1, 2, 3, 6, 9], _predicate: (Function)), _transform: (Function))

bằng việc dùng thêm từ khóa lazy để chỉ định rằng mảng “lười” là mảng mà chúng ta cần thao tác. Khi đã xác định bản chất nó như vậy, thì nó lười đi trông thấy: không 1 dòng print nào của filter và map được hiển thị.

Rõ ràng nó làm biếng. Thêm dòng code tiếp vào sau đoạn trên:

print(modifiedLazyNumbers.first!)
/*
Prints:
Lazy Even number filter
Lazy Even number filter
Lazy Doubling the number
4
*/

Vậy là bây giờ đã thấy xuất hiện 2 dòng print và 1 dòng double và kết quả là 4 sau khi nhân đôi số đầu tiên lên.

Tại sao lại vậy? Do yêu cầu chúng ta là chỉ lấy phần tử đầu tiên, cho nên mảng lười chỉ thao tác cho đến khi phần tử đầu tiên xuất hiện. Do vậy chúng ta hạn chế được những động tác thừa không cần thiết.

Rõ ràng trường hợp này là 1 sự lười = thông minh phải không nào 😆

Một trường hợp hay áp dụng trong thực tế:

lập trình swiftTìm kiếm trong ứng dụng

Trong trường hợp như hình, khi chúng ta tìm chữ nào đó thì ứng dụng sẽ bắt đầu hiển thị các places liên quan tới và đồng thời load image cho place đó.

Ví dụ chúng ta muốn tìm các địa điểm bắt đầu bằng chữ “h”.

Khi không dùng lazy, theo dõi đoạn code sau:

let places = ["Ho Chi Minh", "Ha Noi", "Hue", "Da Nang", "Vung Tau", "Nha Trang"]
places
.filter { place in
print("filtered name")
return place.lowercased().first == "h"
}.forEach { place in
print("Fetch image for \(place)")
}

/*
Ket qua:
filtered name
filtered name
filtered name
filtered name
filtered name
filtered name
Fetch image for Ho Chi Minh
Fetch image for Ha Noi
Fetch image for Hue
*/

Như kết quả, chúng ta sẽ duyệt toàn bộ những địa điểm và lấy các địa điểm có tên bắt đầu bằng chữ “h”, sau đó rồi mới fetch ảnh về.

Trường hợp dùng lazy, theo dõi đoạn code sau:

 let places = ["Ho Chi Minh", "Ha Noi", "Hue", "Da Nang", "Vung Tau", "Nha Trang"]
places.lazy
.filter { place in
print("filtered name")
return place.lowercased().first == "h"
}.forEach { place in
print("Fetch image for \(place)")
}
/*
Ket qua:
filtered name
Fetch image for Ho Chi Minh
filtered name
Fetch image for Ha Noi
filtered name
Fetch image for Hue
filtered name
filtered name
*/

Chúng ta tìm ra Ho Chi Minh, sau đó ảnh của địa điểm này sẽ được load luôn. Sau đó tìm ra Ha Noi, va Hue cũng làm tương tự. Rõ ràng nếu không có lazy, thì mảng sẽ phải duyệt qua toàn bộ, sau đó mới fetch ảnh về. Còn với lazy, chúng ta duyệt – tìm ra – fetch về luôn. Theo bạn phương án lười này có thông minh không? Rõ ràng nó được 💯 điểm thông minh cho trường hợp này.

Tuyển dụng lập trình IOS lương cao hấp dẫn tại đây.

Lazy không lưu cache

Lười thì cũng thông minh đấy, nhưng 1 số trường hợp lại không thực sự như vậy. OK, nói đi thì phải nói lại, dù sao thì chúng ta phải quyết định nó sẽ dùng như nào, nên phải hiểu bản chất của nó trước.

Quay lại ví dụ đầu tiên, chúng ta theo dõi đoạn code sau:

let modifiedLazyNumbers = numbers.lazy
.filter { number in
print("Lazy Even number filter")
return number % 2 == 0
}.map { number -> Int in
print("Lazy Doubling the number")
return number * 2
}
print(modifiedLazyNumbers.first!)
print(modifiedLazyNumbers.first!)
/*
Prints:
Lazy Even number filter
Lazy Even number filter
Lazy Doubling the number
4
Lazy Even number filter
Lazy Even number filter
Lazy Doubling the number
4
*/

Chúng ta yêu cầu lấy phần tử đầu tiên 2 lần qua 2 lệnh print, và để ý đoạn log mà chương trình trả về, nó hiển thị rất nhiều!. Với các mảng bình thường, theo dõi đoạn code sau:

let modifiedNumbers = numbers
.filter { number in
print("Lazy Even number filter")
return number % 2 == 0
}.map { number -> Int in
print("Lazy Doubling the number")
return number * 2
}
print(modifiedNumbers.first!)
print(modifiedNumbers.first!)
/*
Prints:
Lazy Even number filter
Lazy Even number filter
Lazy Even number filter
Lazy Even number filter
Lazy Even number filter
Lazy Doubling the number
Lazy Doubling the number
4
4
*/

Nó duyệt qua 1 lần, và lưu vào 1 mảng, sau đó chúng ta dù có gọi nhiều lần phần tử đầu tiên, nó chỉ hiển thị kết quả cuối cùng.

Vậy trong trường hợp này, các bạn sẽ rút ra 2 kết luận:

  • lazy thì không lưu vào cache. Nó sẽ thực hiện lại toàn bộ quy trình từ đầu.
  • lazy trong trường hợp này là ngu ngốc!

OK, vậy để đặt lại cái tiêu đề bài viết cho đỡ chửi thì có lẽ là dùng lazy như nào cho thông minh phải không? Nhưng thôi tôi xin phép để tiêu đề vậy để nhận thêm gạch đá.

Luôn tận dụng API của apple

Với ví dụ trên, chúng ta có thể thay đổi bằng cách dùng API có sẵn của apple và nhận được kết quả tương tự.

Xem xét ví dụ sau:

let collectionOfNumbers = (1…1000000)
let lazyFirst = collectionOfNumbers.lazy
.filter {
print("filter")
return $0 % 2 == 0
}.first
print(lazyFirst) // Prints: 2

Với mảng nhiều phần tử như trên, lazy chỉ thực hiện đúng 2 lần cho ngữ cảnh trên. Và Apple cũng có 1 API để làm điều đó:

let firstWhere = collectionOfNumbers.first(where: { $0 % 2 == 0 })
print(firstWhere) // Prints: 2

Tội gì không dùng hàng Apple anh em nhỉ?

Những trường hợp khác để tối ưu hiệu năng cho ứng dụng

Apple có nhiều API lắm, kết quả thì giống nhau và đây là 1 vài sự so sánh giữa chúng.

Nên dùng contains thay vì first(where:) != nil

Hai API này cùng xác định 1 mảng có chứa 1 phần tử nào đó hay không, nhưng hiệu năng contains sẽ tốt hơn là first(where:) != nil.

Phương án tốt:

let numbers = [0, 1, 2, 3] 
numbers.contains(1)

Phương án tệ:

let numbers = [0, 1, 2, 3] 
numbers.filter { number in number == 1 }.isEmpty == false 
numbers.first(where: { number in number == 1 }) != nil

Dùng isEmpty thay vì count == 0

Khi để kiểm tra 1 mảng có rỗng hay không thì dùng property isEmpty. Còn nếu bạn dùng count, nếu 1 mảng không tuân theo RandomAccessCollection protocol, việc tính count sẽ duyệt qua toàn bộ phần tử của mảng.

Best practice:

let numbers = [] 
numbers.isEmpty

Bad practice:

let numbers = [] 
numbers.count == 0

Tương tự với string – được coi là tập hợp của các ký tự thì dùng isEmpty vẫn là tốt hơn dùng so sánh count với 0.

Lọc phần tử đầu tiên trong tập hợp với điều kiện

Có 2 cách để thực hiện điều đó: dùng filter và sau đó dùng first. Hoặc dùng first where.

Cách 1, chúng ta sẽ duyệt toàn bộ tập hợp, sau đó lấy phần tử đầu tiên. Cách 2 chúng duyệt cho đến khi nào tìm thấy phần tử đầu tiên thì dùng. Rõ ràng là tốt hơn.

Best practice:

let numbers = [3, 7, 4, -2, 9, -6, 10, 1] 
let firstNegative = numbers.first(where: { $0 < 0 })

Bad practice:

let numbers = [3, 7, 4, -2, 9, -6, 10, 1] 
let firstNegative = numbers.filter { $0 < 0 }.first

Điều này cũng đúng với các trường hợp last where.

Tìm phần tử lớn nhất, nhỏ nhất của tập hợp

Có 2 cách để tìm phần tử lớn nhất, nhỏ nhất của mảng:

  • dùng toán tử có sẵn min hoặc max.
  • Dùng toán tử sort sau đó lấy first để tìm min hoặc last để tìm max

Best practice:

let numbers = [0, 4, 2, 8] 
let minNumber = numbers.min() 
let maxNumber = numbers.max()

Bad practice:

let numbers = [0, 4, 2, 8] 
let minNumber = numbers.sorted().first 
let maxNumber = numbers.sorted().last

Xác định toàn bộ mảng phù hợp với điều kiện nào đó

Ví dụ chúng ta muốn mảng chứa toàn bộ là số chẵn. Có 2 phương án để dùng.

Best practice:

let numbers = [0, 2, 4, 6] 
let allEven = numbers.allSatisfy { $0 % 2 == 0 }

Toán tử allSatisfy(_:) được giới thiệu ở swift 4.2 và bạn có thể tham khảo thêm tại đây: SE-0207

Bad practice:

let numbers = [0, 2, 4, 6] 
let allEven = numbers.filter { $0 % 2 != 0 }.isEmpty

Kết luận

Chúng ta có nhiều cách để tiếp cận 1 vấn đề, nhưng sẽ có phương án tốt hơn phương án kia. Việc sử dụng hoàn toàn phụ thuộc vào trình độ của bạn. Do vậy đôi khi giả sử tôi kém, tôi không hiểu, thì bạn có thể dùng tool để check: Swiftlint ở đây. Tool này sẽ cảnh báo những cái mà bạn đang dùng hơi ngáo ngổ, và suggest cho bạn phương án tốt hơn. OK, đó là tất cả.

Toàn bộ bài viết được lấy từ nguồn ở đây và có sửa đổi 1 chút:

Performance, functional programming and collections in Swift

Bài viết gốc được đăng tải tại codetoanbug.com
Xem thêm:

Việc làm IT mọi cấp độ được TopDev cập nhật mỗi ngày, tham khảo ngay!

Xu hướng phát triển của IoT hiện nay

xu hướng phát triển của IoT

IoT là thuật ngữ được nhắc đến rất nhiều trên các diễn đàn công nghệ trong các năm trở lại đây, đặc biệt sau đại dịch Covid-19. Khi sự tương tác giữa con người và con người ngày càng hạn chế thì IoT mang đến cho chúng ta 1 giải pháp tuyệt vời để giao tiếp với các đồ vật, thiết bị và tận hưởng sự phục vụ mà chúng mang lại cho cuộc sống hiện đại.

Hãy thử tưởng tượng đến cuộc sống mà: Ô tô có thể tự lái, bóng đèn tự bật tắt, cây cối được tự tưới nước, … và quan trọng hơn là chúng ta có thể theo dõi (là theo dõi chứ không phải điều khiển nhé) tất cả thiết bị đó qua 1 màn hình điện thoại; IoT là xu hướng tất yếu cho quá trình đổi mới, cái gọi là cách mạng công nghiệp 4.0 hiện nay.

Trong bài viết này, mình cùng các bạn sẽ đi tìm hiểu về Xu hướng phát triển của IoT hiện nay cũng như cơ hội dành cho lập trình viên trong lĩnh vực này nhé.

IoT mang lại lợi ích gì cho người sử dụng?

“Mọi đồ vật sẽ trở nên thông minh hơn” – đấy là lợi ích mà IoT mang lại. Chúng ta đã quá quen với smartphone, smart tivi, hay gần hơn là smarthome, smartkey, …, thì giờ với IoT chúng ta có mọi thứ xung quanh đều thông minh: đèn thông tin – biết lúc nào cần bật khi có người và tắt để tiết kiệm điện, máy giặt thông minh – tự điều chỉnh lượng nước phù hợp với số lượng quần áo, hay ngay đến rèm cửa cũng thông minh – chủ động đóng mở theo ánh sáng mặt trời.

xu hướng phát triển của IoT

Nguồn ảnh: circleid.com

IoT hiện nay

IoT (Internet of Things) là một bức tranh khi mà mỗi đồ vật, con người được cung cấp khả năng truyền tải và trao đổi thông tin qua một mạng duy nhất mà không cần đến sự tương tác trực tiếp giữa người với người hay máy tính. Việc kết nối có thể được thực hiện qua Wifi, 4G hay 5G, Bluetooth, …

Khái niệm IoT được ra đời từ năm 1999, tuy nhiên phải trải qua gần 20 năm, nhờ sự phát triển đầy đủ về phần cứng, các phương thức kết nối thì nó mới phát huy được hết tiềm năng, những ứng dụng của nó vào các hoạt động thực tiễn và kinh doanh.

Theo Gartner, đến năm 2020 thế giới có khoảng 20 tỷ thiết bị đã sử dụng IoT và con số này dự kiến sẽ lên tới 41,6 tỷ thiết bị IoT được kết nối. Rõ ràng thị trường IoT thực sự rất lớn và tiềm năng:

IoT là gì

Nguồn: cioandleader.com

IoT và cách mạng công nghiệp 4.0

Cách mạng công nghiệp 4.0 là sự tự động hóa và trao đổi dữ liệu trong công nghệ sản xuất bao gồm các hệ thống mạng vật lý, mạng Internet kết nối vạn vật và điện toán đám mây. Trong đó, con người có thể giao tiếp và giám sát thiết bị thay vì phải trực tiếp vận hành chúng. Chính vì thế IoT đóng vai trò quan trọng trong nền CN 4.0, nhiệm vụ của nó chính là kết nối mọi thứ với nhau, thu thập mọi dữ liệu từ các cảm biến để con người có thể giám sát được chúng.

Chúng  ta có thể hình dung trong nền công nghiệp 4.0; AIBig Data là bộ xử lý dữ liệu, nhận về 1 lượng lớn dữ liệu , xử lý và đưa ra kết luận đúng đắn; Robotic thay thế sức lao động của con người bằng khả năng vận hành không mệt mỏi của máy móc; thì IoT chính là mạng lưới kết nối 2 thứ trên, chúng giúp thu thập dữ liệu và đưa các phản ứng.

IoT và cách mạng công nghiệp 4.0

Nguồn: westerndigital.com

IoT bị tác động thế nào bởi đại dịch Covid-19

Với sự tác động của đại dịch Covid-19, các yêu cầu về khoảng cách xã hội đã thúc đẩy công việc từ xa, nhu cầu về các tài nguyên máy tính phân tán nằm gần thiết bị và người dùng, cách xa các vị trí tập trung như văn phòng. Khi các nhân viên đều làm việc ở nhà , mọi thứ đều cần sự tự động hóa và được theo dõi từ xa một cách cần thiết hơn – và IoT ở đây để giúp chúng ta làm những việc đó.

Nhìn một cách tích cực thì đại dịch Covid-19 giúp IoT ngày càng có vai trò quan trọng trong mọi lĩnh vực: học tập thi cử từ xa – cần các thiết bị theo dõi, giám sát; khám chữa bệnh từ xa – cần những nguồn lực y tế kỹ thuật số.

IoT bị tác động thế nào bởi đại dịch Covid-19

Nguồn: health.gov.vn

Cơ hội tuyệt vời dành cho các lập trình viên

Hiện nay các doanh nghiệp, công ty trong mọi lĩnh vực đều đang cố gắng đưa IoT vào sử dụng trong kinh doanh của mình một cách hiệu quả; vì thế số lượng dự án, việc làm về các mảng công nghệ liên quan đến IoT đang tăng lên rất nhanh, kèm theo đó mức lương khởi điểm cũng là cao hơn so với các lĩnh vực công nghệ khác.

Lập trình viên IoT tại các tổ chức đóng vai trò nghiên cứu, phát triển nền tảng, thiết bị thông minh, đưa ra các giải pháp mới; cùng với đó là việc thiết kế lắp đặt vận hành, bảo trì giám sát các sản phẩm IoT. Sự đa dạng thiết bị IoT từ phần cứng đến phần mềm cũng tạo ra cho lập trình viên sự đa dạng trong công việc và kèm theo đó là những thử thách mới trong từng dự án mà bạn tham gia. 

Để theo đuổi lập trình IoT, các bạn lập trình viên với đam mê của bản thân hãy bắt đầu ngay từ bây giờ, nắm bắt được xu hướng phát triển của IoT hiện nay để bước vào ngành. Điều thú vị nhất của lập trình IoT là các bạn sẽ được làm việc với các thiết bị phần cứng rất đa dạng và thú vị, hơn hết là khả năng ứng dụng ngay vào được trong đời sống hàng ngày. Chúc các bạn thành công với sự lựa chọn của mình.

Tác giả: Phạm Minh Khoa

Xem thêm:

Tìm kiếm việc làm IT mới nhất tại TopDev!

Tuple Python là gì? Tìm hiểu về tuple python

Tuple trong lập trình Python. Những điều cần biết

Với anh em nào chưa biết xài Tuple, bài viết này giúp đỡ được, với anh em nào đã xài Tuple và quên té cái giống và khác với List, đọc bài này cũng ổn.

Nói chung là bài viết Tuple Python này dành cho mọi người, mọi trình độ. Đọc vui anh em nhớ ủng hộ nha!. Viết khá cụ thể, giống, khác, ví dụ ví dại rõ ràng đầy đủ.

Bắt đầu ngay thôi nào!

1. Tuple là gì?

Bắt đầu với đặc sản là lướt qua định nghĩa.

A Tuple is also a sequence data type that can contain elements of different data types, but these are immutable in nature. In other words, a tuple is a collection of Python objects separated by commas. The tuple is faster than the list because of static in nature. Tuple là kiểu dữ liệu chuỗi bao gồm nhiều các thành phần có kiểu dữ liệu khác nhau, nhưng nó là không thể thay đổi được. Nói một các khác, tuple là một object Collection phân cách nhau bằng dấu phẩy. Tuple nhanh hơn List cũng ở chỗ này, do tĩnh (static) không thể thay đổi được.

  Biến toàn cục (global), biến cục bộ (local), biến nonlocal trong Python
  Biến và kiểu dữ liệu cơ bản trong Python

Sau định nghĩa thì là syntax, làm gì thì làm vẫn phải lướt qua syntax nha.

Ví dụ này bao gồm nhiều loại tuples lun ha.

# Nhiều loại tuple 

# Empty tuple
tuple_rong = ()
print(tuple_rong)

# Tuple bao gồm toàn số
tuple_toan_so = (1, 2, 3)
print(tuple_toan_so)

# Tuple nhiều loại dữ liệu
tuple_nhieu_loai_du_lieu = (true, "Kieu Chuoi", 5.2)
print(tuple_nhieu_loai_du_lieu)

# Tuple kết hợp nhiều loại
tuple_hon_hop = ("hon hop", [true, false, 6], (9, 2, 3))
print(tuple_hon_hop)

Chỗ nhanh chậm này mình sẽ phân tích kỹ ở mục khác nhau cho anh em. Nhưng mà biết được tuple là immutable rồi thì cái nào không đổi nhớ dùng tuple nha. Không chơi lầy chày cối List nha.

2. Sử dụng Tuple

2.1 Sử dụng

2.1.1 Phương thức hỗ trợ

Tuple cũng hỗ trợ 2 phương thức chính là count và index. Do tính chất immutable nên chắc chắn không thể có các method add và remove nha.

tuple_phuong_thuc = ('t', 'u', 'p', 'l', 'e', 'e', )

print(tuple_phuong_thuc.count('e'))  # Output: 2
print(tuple_phuong_thuc.index('l'))  # Output: 3

2.1.2 Xóa tuple

Xóa một phần tử trong tuple

# Xóa tuple như thế nào
xoa_tuple = ('x', 'o', 'a', 't', 'a', 't', 'c', 'a')

# Tuple không hỗ trợ xóa phần tử do là immutable
del xoa_tuple[3]

# Nhưng có thể xóa toàn bộ tuple
del xoa_tuple

# Lỗi, xoa_tuple không được định nghĩa
print(xoa_tuple)

2.1.3 Negative index (index âm)

Truy cập với index âm, tuple cho phép access với index âm nha anh em.

# Index âm thì tuple sẽ index từ sau ra trước
tuple_index_am = ('t', 'o', 'p', 'd', 'e', 'v')

# Output: 'v'
print(tuple_index_am[-1])

# Output: 't'
print(tuple_index_am[-6])

2.1.4 Slicing

Tuple cũng hỗ trợ cắt các giá trị trong tuple, lưu ý là lấy giá trị để sử dụng chứ về mặt bản chất là không thay đổi được tuple đã định nghĩa ban đầu nha.

# Truy cập tuple với slicing
my_tuple = ('t','r','u','y','c','a','p','i','z')

# Phần tử 1 cho tới 4, có tổng 3
# Output: ('r', 'u', 'y')
print(my_tuple[1:4])

  Tuple Python là gì? Tìm hiểu về tuple python
”]

2.2 Một số lưu ý

Trường hợp chưa muốn định nghĩa giá trị, có thể định nghĩa một Tuple empty như sau:

# Nếu chưa có sẵn các giá trị nhưng vẫn muốn sử dụng tuple, ta có thể thoải mái định nghĩa tuple empty
tuple_empty = ()

Có điều empty thì dễ, nhưng có 1 thì nhớ thêm dấu phẩy (comma) vào nha anh em. Mỗi dấu phẩy thôi nhưng mà quan trọng nha. Không add thì python không hiểu là Tuple đâu á.

# Nếu chưa có sẵn các giá trị nhưng vẫn muốn sử dụng tuple, ta có thể thoải mái định nghĩa tuple empty
tuple_empty = ("kien dep trai",)

Rồi, biết ông đẹp trai rồi, nói hoài. Bài nào cũng ví dụ. Khổ ghê =))). Ví dụ phía trên toàn là cùng kiểu dữ liệu như string hay integers. Lỡ mà tui cần mix nhiều data types (kiểu dữ liệu) với nhau thì được không?.

Được chớ sao không?

You can create a tuple or a list that contains just a sequence of strings, just a sequence of integers, or just a sequence of Boolean values, with each item in the sequence separated by a comma. Bạn có thể tạo tuple hoặc list bao gồm danh sách các chuỗi, hoặc số, hoặc các giá trị boolean. Chỉ cần các nhau các item bởi dấu phẩy là được

# Với tuple mixed thoải mái nha anh em
my_information = tuple("Kien",27,True,"xau",7,"trai",False)

Rồi đó, vừa lòng chưa =))). Phía trên quên ví dụ quên cái dấu phẩy, nếu thiếu sẽ báo lỗi nha anh em

# Nhớ dấu phẩy (comma) nha anh em
>>>tuple_loi = ("Kie" 50,True,"Blog",50)
File "<stdin>", line 1
    >>>tuple_loi = ("Kie" 50,True,"Blog",50)
    ^
SyntaxError: invalid syntax

Tuyển dụng Python mọi cấp độ tại đây!

3. Giống ghê, giữa tuple và list

Theo như cái định nghĩa cụ thể rõ ràng của Tuple ở phía trên, thì rõ ràng cả hai ông thần Tuple trong python và List trong python đều có thể lưu nhiều giá trị vào duy nhất một biến.

Rõ là thế, điểm giống đầu tiên:

3.1 Cú pháp (syntax)

# List lưu nhiều giá trị trong một biến duy nhất
tuple_1 = ["Hoc", "Python", "Khong", "Khó"]. 

# Tuple cũng lưu nhiều giá trị trong duy nhất 1 biến tuple_2
tuple_2 = ("Hoc", "Python", "Khong", "Khó")

Phía trên là ví dụ về sự giống nhau giữa Tuple và List. Đáng ra sẽ nói vào mục khác nhau, nhưng thôi do khác rành rành ra nên nói luôn ở đây.

The only difference is in the syntax: you create tuples by surrounding the items inside them with opening and closing round brackets, (), whereas lists are denoted and defined by the presence of opening and closing square brackets,[]. Điểm khác biệt rõ ràng dễ nhận ra nhất là cú pháp: với tuple thì ta tạo ra danh sách các phần tử và đóng gói lại trong dấu ngoặc (), trong khi đó list thì định nghĩa các item và sau đó đóng mở trong dấu ngoặc vuông []

  Python là gì? Tổng hợp kiến thức cho người mới bắt đầu

3.2 Truy cập (access)

Cả tuple và list đều là ordered collection nha anh em (có thứ tự). Thứ tự này thì không thể thay đổi được ngay sau khi đã tạo ra. Cái này cũng được gọi là định danh duy nhất (unique identifier – index). Cả list và tuple đều bắt đầu với index là 0 cho phần tử đầu tiên, 1 cho phần tử thứ hai.

# Cả List và Tuple đều access bằng index
>>>ten = ("Nguyen","Le","Trung","Kien")

>>>ten[2]
'Le'

>>>ngon_ngu_lap_trinh = ["Python","JavaScript","Java","C"]

>>>ngon_ngu_lap_trinh[0]
'Python'

3.3 Unpacking (bẻ ra – dịch tạm thế nha)

Cả list và tuple sau khi khai báo, anh em có thể phân tích từng item trong đó ra và gán cho các biến khác. Có ví dụ thì dễ phân tích hơn.

# Khai báo tuple trước (không đẹp xấu gì nữa), tên bỏ đi 1 chữ lót, tính Le là chữ lót nha
>>>ten_toi = ("Nguyen","Le","Kien")

# Giờ muốn lấy họ, tên lót và tên ra thành các biến, 3 biến phía dưới nha
>>>ho,ten_lot,ten = ten_toi

>>>ho
'Nguyen'

>>>ten_lot
'Le'

>>>ten
'Kien'

Bóc tách từng giá trị trong tuple và list ra và gán cho các biến khác độc lập thì gọi là unpacking. Cả list và tuple trong Python đều hỗ trợ nha.

4. Ơ thế tuple và list khác nhau gì không?

Xin thưa là có, từ nhỏ bé xinh xinh cho tới lớn lớn cũng xinh xinh. Cái này mình cũng nói ở trên rồi ha. Nho nhỏ nhưng nhớ được thì tốt.

4.1 Mutable và immutabe (thay đổi và không thay đổi)

Đầu tiên cũng là các khác biệt rõ ràng nhất. List thì có thể thay đổi được, nhưng tuple thì không. Một khi đã khai báo tuple thì không thể thay đổi giá trị trong đó.

# List có thể thay đổi được phần tử
list_co_the_doi = [4, 2, 3]
list_co_the_doi[1] = 9

print(list_co_the_doi) = [9, 2, 3]

# Tuple thì cần nha, không cần Python không hiểu
tuple_khong_doi = (4, 2, 3, [6, 5])

# Lỗi, không thể gán giá trị cho tuple
# tuple_khong_doi[1] = 9

4.2 Tốc độ

Do tuple là immutable (không thể thay đổi), nên tốc độ duyệt hoặc lấy theo index của tuple rất nhanh, hơn List.

List chậm hơn so với tuple về cả mặt thời gian và bộ nhớ (memory).
Nguồn ảnh / Source: afshin.io
List Tuple
List có thể thay đổi được Tuple không thể thay đổi được
List tốt hơn về mặt performance ở một số thao tác như insert hoặc delete Tuple chỉ thích hợp để truy vấn các phần tử trong tuple
List tiêu tốn nhiều bộ nhớ hơn Khi so sánh với list, tuple tiêu tốn ít bộ nhớ hơn
Bản thân list có một số phương thức được tích hợp sẵn Tuple không có nhiều phương thức định sẵn

5. Tham khảo thêm về tuple trong python

À anh em xài tuple nhớ đặt tên mục đích nha, như list. Chứ không là phải nhìn value từng item trong đó để mà hiểu á. Code clean, please follow the rule!.

tuple-trong-lap-trinh-python

Cảm ơn anh em đã đọc bài – Thank you for your time – Happy coding!

Tác giả: Kiên Nguyễn

Top IT Jobs hot dành riêng cho Top Developers tại TopDev!

Câu chuyện sử dụng VPN

câu chuyện sử dụng vpn

Tác giả: Nguyễn Hồng Quân

Tôi thỉnh thoảng có nhu cầu sử dụng mạng VPN. Trong khi nhiều bạn dùng VPN để vượt qua bức tường chặn các trang web mà chính phủ không mong muốn thì mục đích dùng VPN của tôi lại nhằm phục vụ cho IoT, tạo đường truy cập các máy tính nhúng (BeagleBone, Raspberry Pi) từ xa qua Internet, phục vụ cho công việc.

Các máy tính nhúng của tôi hay được đặt trong một mạng LAN mà router của nó tôi không được can thiệp, nên không thể cấu hình port forward để truy cập trực tiếp từ ngoài Internet được.

No-VPN

Bằng cách thiết lập VPN, tôi sẽ có một mạng LAN ảo giữa laptop của tôi đang ở một quán nước dọc đường và máy tính nhúng đang đặt ở một căn phòng nào đó.

With-VPN

Mặc dù trên thị trường đã có nhiều giải pháp VPN, nhưng những giải pháp VPN “hay nghe tên” như OpenVPN, PPTP, IPSec thì có quá trình cài đặt, kết nối phức tạp. Sự phức tạp này đến từ việc chúng đòi hỏi sử dụng các chứng chỉ số (X.509 certificate).

Mà đụng đến chứng chỉ số là đụng đến việc có nhiều file để cấu hình, phải có bước kí chữ kí số, chứng chỉ số của mình phải được kí bởi một nhà cung cấp chứng thực số (Certificate Authority) có uy tín, không thì kết nối vào mạng VPN sẽ bị từ chối. Chưa kể, các giải pháp này hay bị ca thán vì tốc độ chậm chạp. Các dịch vụ VPN ở dạng cloud service thì không có phần mềm client dành cho máy tính nhúng nên tôi chưa có điều kiện thử.

Hai năm trước, nhu cầu sử dụng VPN của tôi đến từ việc nhóm AgriConnect chúng tôi xây dựng phòng thí nghiệm trồng nấm ứng dụng IoT. Phần mềm điều khiển trung tâm được cho chạy trên một board BeagleBone Black đặt ngay tại nhà trồng nấm. Chúng tôi thì cần truy cập vào BeagleBone để xem thông số môi trường của nhà trồng nấm, đồng thời đặt lịch điều khiển các thiết bị.

Thời gian đầu chưa được sử dụng đường mạng riêng nên chúng tôi phải tìm đến phương án VPN để có thể truy cập từ xa. Giải pháp VPN đầu tiên mà chúng tôi dùng là LogMeIn Hamachi. Dùng được một thời gian thì phát hiện phần mềm client dành cho Windows của Hamachi kém ổn định quá, thế là nghiên cứu tìm giải pháp VPN khác. Giải pháp sau đó tôi tìm được là SoftEther VPN. Đây là một phần mềm VPN còn khá mới, mã nguồn mở, và cho phép đăng nhập bằng password chứ không nhất thiết phải dùng certificate. Trớ trêu là phần mềm này chủ yếu nhắm đến cung cấp cho những người chống chính quyền cộng sản TQ có phương tiện vượt tường lửa Internet của TQ. Cũng phải mất kha khá thời gian để biết cách setup trên server, vì tài liệu được tổ chức, đặt tựa đề theo kiểu rất khó tra cứu. Đã vậy tài liệu chỉ hướng dẫn chi tiết về phần mềm có giao diện chạy trên Windows, trong khi bản dành cho Linux, chỉ có giao diện dòng lệnh thì hướng dẫn rất sơ sài, chỉ có liệt kê, giải thích từng tên gọi trong cấu hình, chứ không hướng dẫn làm gì trước, làm gi sau.

Tuyển dụng kỹ sư lập trình nhúng mới nhất tại đây

Trong quá trình mò mẫm cài đặt SoftEther VPN, tôi thậm chí còn đóng góp sửa lỗi cho dự án. Như vậy hóa ra mình đã góp một phần giúp những người chống Cộng.

Sau khi thử nghiệm SoftEther VPN thành công thì nhà nấm của chúng tôi được di dời đến địa điểm mới, có mạng riêng, nên nhu cầu VPN không còn nữa. Tôi đã định viết thành tài liệu hướng dẫn cách setup SoftEther VPN này, công bố rộng rãi, để giới thiệu SoftEther VPN đến nhiều người hơn, nhưng chưa có thời gian. Bản hướng dẫn sơ lược thì cũng đã có, dưới dạng tài liệu nội bộ của AgriConnect (bản này viết ngắn gọn, không có giải thích, không có dẫn dắt nên không hợp với đại chúng để mà tung ra).

Bẵng đi một thời gian thì nhu cầu sử dụng VPN lại quay lại. Gần đây tôi tham gia vào dự án SUSI.AI Smart Speaker, tạo dựng phần mềm trợ lý ảo (virtual assistant) mã nguồn mở, chạy trên máy tính nhúng Raspberry Pi. Nó sẽ giống Google Home, nhưng là mã nguồn mở nên ai cũng có quyền lấy về, tự làm mạch, tự cài phần mềm lên mà xài. Một trong những việc cần làm là viết một script để tạo ra file ảnh hệ điều hành, trong đó có cài sẵn phần mềm SUSI.AI, để người dùng tải về cấy vào thẻ nhớ và sử dụng với board Raspberry Pi của họ.

Vì script này chạy rất lâu, mà tôi thường hay di chuyển, nên tôi cần chạy script này trên một server, để tôi có thể truy cập từ xa, theo dõi quá trình chạy của script. Ban đầu tôi thuê server của Scaleway để chạy, nhưng server của họ bị một số bug, script không chạy được, nên trong lúc vừa debug, tôi vừa phải xoay qua phương án cho chạy trên Raspberry Pi của tôi, nghĩa là phải thiết lập VPN cho nó để tôi có thể truy cập từ xa.

Lần này thì tôi không muốn dùng SoftEther nữa. Trong lúc thử nghiệm SoftEther, tôi vẫn còn sự bứt rứt không hài lòng. Vốn là người sử dụng Linux lâu năm nên tôi rất ưng ý SSH và cặp khóa SSH. Phương thức xác minh bằng SSH key như thế này vừa đỡ công sức gõ mật khẩu, tránh lộ mật khẩu, mà lại không vướng mắc chuyện CA, chữ kí số như phương thức dùng chứng chỉ số (X509 certificate). Thế nhưng phương thức đăng nhập của SoftEther lại hoặc dùng mật khẩu, hoặc dùng chứng chỉ số, chứ không có cặp khóa như SSH. Tôi vẫn ước ao có một giải pháp VPN cho dùng cặp key như SSH. Cho đến một ngày, tôi phát hiện ra WireGuard.

WireGuard là giải pháp VPN mã nguồn mở, rất mới, và dùng phương thức xác minh y chang SSH, với cặp khóa công khai-riêng, chẳng phải đụng đến mớ chứng chỉ số phiền phức. Chưa hết, WireGuard được cấu trúc theo kiểu mà phần lớn code của nó chạy trong kernel space của Linux, giúp nó có được tốc độ, hiệu năng cao so với các giải pháp VPN khác. Cách cấu hình của nó cũng rất gọn nhẹ, chỉ cần 1 file theo format .ini với 8 dòng (cho client). So với WireGuard thì SoftEther rất rườm rà, phải tạo nhiều lớp: Virtual NIC, Virtual Hub, User, Group, Password . File cấu hình của SoftEther thì không theo format phổ biến (ini, JSON hay YAML, TOML…) mà tự chế format riêng nên không ai dám tự viết file, sợ mắc lỗi. Đây là ví dụ file cấu hình của WireGuard:

[Interface]
PrivateKey = qIN2P8eUhWm2jzu8KIJ4hBb+rt3LT8mJxCuxOcc+l1s=
Address = 192.168.4.2/24
ListenPort = 51820

[Peer]
PublicKey = ZSvxiPwxxvWBeJqzWDWHInDpCY0sTpADcb2A4jom13o=
Endpoint = my_public_server:51820
AllowedIPs = 192.168.4.0/24

Mặc dù đơn giản, nhưng WireGuard vẫn còn bị hụt ở chuyện tài liệu. Tôi cũng phải tìm tài liệu ở nhiều nơi, so sánh qua lại mới mò ra được cấu hình phù hợp cho mô hình mình mong muốn. Thế nên, trong bài sau, tôi sẽ viết một hướng dẫn ngắn về WireGuard.

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

Xem thêm:

Đừng bỏ lỡ việc làm IT mọi cấp độ cho Developers tại TopDev

Front-end developer lên trình như thế nào? Bạn đã thực sự hiểu về Front-End?

Front-end developer lên trình như thế nào? Bạn đã thực sự hiểu về Front-End?

Front-end developer chịu trách nhiệm về những công việc tiếp xúc trực tiếp với tương tác của người dùng, trong khi back-end developer lại làm việc với data và những công nghệ đằng sau. Vậy, con đường sự nghiệp của một Front-end developer sẽ diễn ra như thế nào? Và nên tích lũy những gì, ở đâu để lên trình nhanh nhất?

Hãy cùng TopDev trò chuyện cùng chuyên gia đến từ Chợ Tốt và tìm kiếm câu trả lời cho riêng mình nhé!

Đôi nét về khách mời Trần Trọng Thanh

  • Bắt đầu bằng công việc Flash Developer, công việc về những giao diện và trải nghiệm dành cho người dùng tại công ty Pyramid Consulting
  • Công tác 3 năm tại Singapore, vị trí UI Developer và Front-end
  • Về Việt Nam khởi nghiệp với Nâu Studio
  • Hiện tại đang là Principal Web Engineer tại Chợ Tốt

Tại sao anh lại chọn Frontend mà không phải những hướng khác như Backend hay Fullstack?

Mình bắt đầu từ Flash, sau đó tới UI và đến bây giờ là Front-end: tất cả những thứ đó đều xoay quanh một cái giao diện để tương tác trực tiếp với người dùng, điều đó tạo cho mình sự hứng thú rất lớn so với việc làm Backend hay những công việc phải tương tác nhiều với data.

Thử tưởng tượng mình làm ra một cái sản phẩm, 1 front-end website được xuất lên Internet, nó sẽ tiếp xúc được với rất nhiều người dùng trên đó, mình sẽ rất tự hào với sản phẩm, thành quả mà mình đem lại.

Những khái niệm cơ bản về Front-end

Cách hoạt động và một số khái niệm cơ bản cần nắm?

Front-end developer lên trình như thế nào?

Một lập trình viên Front-end – Front-end Developer sẽ làm ra các thành phần cho một website được chạy trực tiếp trên trình duyệt, những gu lập trình đó là HTML, CSS và JavaScript. Tuy nhiên với xu hướng mới bây giờ cùng những kỹ năng sẵn có của các bạn Frontend thì có thể mở rộng hoạt động cho mình như viết ứng dụng cho mobile theo mô hình hybrid, thậm chí là có thể viết những ứng dụng chạy trên desktop về sử dụng nền tảng web để có thể chạy được trên nhiều hệ điều hành khác nhau. Đó chính là một cái nhìn tổng quát về Front-end.

Ngoài ra theo mình các bạn cần có một số kỹ năng khác thiên về giao diện và trải nghiệm người dùng hơn, ví dụ như bạn phải có khả năng quan sát và chú ý đến chi tiết, nó sẽ giúp ích rất nhiều cho quá trình làm việc.

Vì làm với giao diện, bạn phải có sự nhạy cảm với màu sắc về hình khối và bố cục, như phải chú ý đến canh lề, canh hàng giữa các khối trên giao diện của mình hoặc những icon khi đặt vào nó có ngay giữa hay chưa. Đôi khi nếu mình không có những cảm quan đó thì mình sẽ không để ý và bỏ qua.

Và điều cuối cùng anh nghĩ là một bạn frontend giỏi cần có khả năng tưởng tượng, vì khi làm frontend các bạn rất hay sử dụng các animation hoặc những chuyển động trên trang, bằng khả năng tưởng tượng mình sẽ hình dung được trước những cái đó sẽ xảy ra như thế nào rồi từ đó mới thực hiện lại trong code của mình, như thế chắc chắn nó sẽ chuẩn xác hơn.

Sự khác nhau trong công việc hàng ngày của một Fresher Frontend Dev cho đến cấp bậc Junior, Senior là gì?

Công việc của Fresher chủ yếu là các bạn sẽ làm theo những mẫu có sẵn mà các anh chị đi trước đưa ra. Tiếp theo là Junior thì ở trình độ này các bạn đã có thể làm việc được rồi nhưng vẫn phải tiếp tục học vì những kiến thức chuyên sâu như CSS, JavaScript ở trường không có dạy nên các bạn phải vừa học vừa làm. Đây cũng là khoảng thời gian để các bạn thu nhặt kinh nghiệm cho mình và làm sao để cho công việc trở nên thành thục hơn.

Ngoài ra có một vị trí cũng hay được đưa ra mà anh muốn nói đến là Middle. Với Middle hầu như các công việc cơ bản các bạn đã thành thục rồi, nhưng ở vị trí này các bạn bắt đầu tìm hiểu sâu hơn về những công nghệ mới của Frontend ví dụ như là frameworks và có thể giúp đỡ các bạn ở vị trí thấp hơn giải quyết các vấn đề liên quan.

Đối với Senior thì cái mà vị trí này cần quan tâm nhiều nhất chính là user experience. Khi anh càng lên các vị trí cao hơn thì anh thấy các vị trí này càng đòi hỏi phải tập trung hơn và phải có khả năng hỗ trợ hơn ở một góc độ mới là developer experience. Tại sao lại nói như vậy? Vì khi các bạn đã lên đến vị trí Senior rồi thì các bạn phải làm sao hỗ trợ cho team của mình hoạt động hiệu quả hơn, với kinh nghiệm của mình phải đưa ra được những giải pháp cũng như các framework, các thiết kế để làm sao team mình có thể tạo ra những trải nghiệm tốt nhất cho user.

Ứng tuyển ngay các vị trí tuyển dụng Frontend trên TopDev

Nếu muốn theo đuổi con đường Frontend chuyên nghiệp thì cần chuẩn bị những gì, học những nguồn nào theo kinh nghiệm của anh?

Theo anh nghĩ thì trước tiên mình cần trau dồi thêm khả năng đọc tiếng Anh vì những nguồn thông tin cập nhật mới nhất nó không được viết bằng tiếng Việt, nên nếu em có khả năng đọc tốt, khả năng research tốt thì việc học của mình sẽ đạt hiệu quả cao hơn.

Còn về các nguồn học thì anh thấy gần đây có nổi lên một số nguồn platform nổi bật các bạn lập trình viên hay vào để viết bài là Viblo.asia, là trang để các bạn lập trình viên chia sẻ kinh nghiệm của mình. Cũng như các bạn frontend mới học thì các bạn viết rất nhiều bài JavaScript và frontend, đó là những topic mà các bạn rất quan tâm, mình thấy đó cũng là một cái hay. Còn khi các bạn học đại học, để tra cứu thì anh thấy có website Mozilla Developer Network, các bạn có thể search bất cứ chủ đề nào về JavaScript hoặc frontend với các từ khóa thì sẽ cho ra ngay kết quả mà mình tìm. Đây là những nguồn tra cứu công nghệ frontend trội nhất. Còn để thực hành các bạn cũng có thể vào trang “”w3school””, trên đây có khá nhiều các bài tập để mình có thể thực hành.

Nhưng khi mà các bạn lên cao hơn ở tầm vươn ra với thế giới rồi thì anh thấy kênh hữu hiệu nhất để mình cập nhật những kiến thức mới đó chính là thông qua nền tảng Twitter. Vì không giống như Việt Nam, các lập trình viên ở nước ngoài đa số họ sử dụng Twitter nên mình cũng hay lên đó. Đầu tiên các bạn có thể tìm và follow những tác giả của những thư viện vùng mở rồi sau đó từ những người mà bạn follow nó sẽ có các đề xuất để mình tiếp tục follow các topic và các nhân vật KOLs, họ rất hay chia sẻ và giúp mình có thêm những cập nhật mới. Còn nếu các bạn muốn có một nơi để mình tìm những thông tin cập nhật mới bằng tiếng Việt qua facebook thì các bạn có thể tham gia nhóm mà anh đang là admin: Sài Gòn Frontend Developer, anh cũng chỉ join mỗi group đó và hay post lên group đó thôi. Có những cập nhật gì mới hay những cái gì hay ho anh sẽ post lên đó để những bạn có cùng sở thích với mình tiện theo dõi.

Front-end developer lên trình như thế nào?

Công việc của vị trí Principal Engineer là gì?

Anh sẽ nói qua về Chợ Tốt cho những bạn chưa biết, hiện tại đây là nền tảng rao vặt miễn phí lớn nhất ở Việt Nam. Nơi để người dùng vào trang này hiện tại chia làm 2 nền tảng chính là web và mobile app. Nhiệm vụ chính của anh ở vị trí này là xây dựng một đội ngũ Frontend Engineer mạnh ở Chợ Tốt, từ đó anh sẽ giúp công ty và team đưa ra web app cũng như sản phẩm về web có chất lượng cho nền tảng Chợ Tốt của công ty.

Nói sơ qua về cấu trúc của Chợ Tốt, một team gọi là product và test, các bạn sẽ được phân vào nhiều working group theo những nhóm chức năng của nền tảng, như làm về seller và buyer hoặc liên quan đến molitization. Các bạn frontend trong Chợ Tốt sẽ được phân rải rác vào trong những working group này để làm việc cho những chức năng đó. Các frontend developer đó sẽ họp lại với nhau thành một nhóm gọi là Web Charter, anh sẽ như là thư ký của Web Charter này. Những thử thách ở vị trí này có thể kể đến là mình sẽ hỗ trợ các bạn frontend những vấn đề khó hoặc hóc búa, đôi khi những frontend ở trình độ thấp hơn mà họ không thể giải quyết được như xử lý các vấn đề về performances hay mức độ tải trang cho một số app mà Chợ Tốt đang làm.

Ngoài ra anh sẽ giúp thiết kế những framework sử dụng chung giữa các team với nhau. Thêm nữa anh sẽ giúp chuẩn hóa quy trình để làm sao khi các bạn deliver qua app của mình sao cho nó đạt chất lượng cao thông qua các hoạt động như code review hay là những công cụ kiểm tra social code của bạn. Anh cũng tham gia phỏng vấn tuyển dụng các bạn Frontend và Fullstack Dev vào công ty, giúp cho đầu vào đảm bảo và training đào tạo các bạn sau này.

Lời khuyên và bài học thực tế

Thách thức cụ thể của một Tech Lead và một Principal Software Engineer phải đối mặt, cụ thể ở Chợ Tốt là gì?

Anh nghĩ nhìn chung về vị trí này thì những thách thức hay gặp là giúp cải thiện performance cho web app của mình và làm sao để đưa ra được 1 framework chuẩn và bộ thư viện chuẩn cho toàn bộ team. Bây giờ khi mình đã deliver được rất nhiều website và web app rồi thì team size của mình bắt đầu lớn lên, số lượng nhân sự trong team sẽ nhiều lên thì xu hướng bây giờ là làm sao để các bạn front-end tạo ra được những trang web mới hoặc những chức năng mới cho sản phẩm trên web của mình.

Và một thử thách nữa là mình phải tạo ra một cái design system – một nơi để hệ thống hóa lại những component hoặc các mẫu, chuẩn hóa tất cả lại vào một design system giúp cho các bạn front-end tạo thành một module tùy theo yêu cầu của doanh nghiệp.

Một thử thách khác là làm sao để giúp các bạn Dev Engineer làm việc với nhau tốt nhất theo tiêu chuẩn mà mình đưa ra cũng như với các phòng ban khác trong cùng 1 working group.

Rất nhiều thử thách đặt ra vậy thì, liệu có thách thức nào khiến anh nhớ mãi đến tận bây giờ không?

Anh nghĩ trải nghiệm đáng nhớ nhất của mình ở Chợ Tốt là khi anh vào Chợ Tốt cũng được khoảng 3 tháng, lúc đó anh tham gia một dự án đã gần hoàn thành và sắp release. Yêu cầu lúc đó là đánh giá performance, tốc độ tải trang của app đó trước khi đưa lên production. Kết quả đánh giá khá thấp, đó cũng là challenge đầu tiên của anh, nhiệm vụ của anh cùng với các bạn trong team lúc đó là làm sao để cải thiện điểm này lên.

Bọn anh cùng chung tay đánh giá và xem xét các điểm, các nút thắt cổ chai hoặc những vấn đề đối với bộ đóng gói, kích thước size của nó khá lớn, có một số vấn đề như vậy. Cũng mất một khoảng thời gian cùng làm việc với các bạn trong team sau đó đã cải thiện được rất nhiều. Lúc đó theo anh nhớ thì tool lighthouse của front-end điểm này đã được cải thiện ít nhất cũng gấp 2, gấp 3, tất nhiên là điểm tuyệt đối thì nó cũng không cao lắm so với mong đợi, nhưng so với trước khi anh tiếp nhận và kết quả cuối cùng thì nó đã cải thiện rất nhiều. Nhờ đó anh cũng rút ra được khá nhiều các bài học để đưa ra hướng dẫn và lưu ý để các bạn Junior sau này làm việc có thể cải thiện được những nút thắt cổ chai đó.

Cách anh phân bổ tasks và quản lý team như thế nào?

Vị trí của anh thì đóng vai trò như người điều phối là chính và thư ký cho một nhóm các bạn Front-end Engineer. Các bạn sẽ làm việc cùng với một Fullstack team cùng với những bạn khác như backend, dev, mobile dev và product order, tester. Working group đó chạy theo mô hình scrum như mọi người cũng hay biết. Ở vị trí web charter anh sẽ cố gắng đưa ra một số hoạt động như là họp định kỳ để khi đó mình nắm được tình hình và cách làm việc của các bạn trong working group như thế nào, các bạn có khó khăn gì thì trong buổi họp định kỳ đó mình sẽ đưa ra để mọi người cùng nhau giải quyết. Đó cũng là cách để mình hiểu các bạn hơn, nắm được bạn đang làm gì trong công việc của bạn đó.

Đa số là hoạt động online, mình sử dụng Zira và có các dự án trên đó, mình sẽ đưa ra các ý kiến như về chuẩn hóa, conversion hay những quy chuẩn của team, tùy theo mỗi quy trình mà mình sẽ đưa ra những task cụ thể. Trong các buổi họp chung mình sẽ hướng dẫn cho các bạn, từ đó các bạn sẽ triển khai trong công buổi họp để các bạn liên quan thảo luận với nhau.

Mất bao lâu để trở thành một Senior Front-end Dev? Lời khuyên cho các bạn hiện đang là Junior “trong thời gian dài”.

Front-end developer lên trình như thế nào?

Theo quan sát và đánh giá của anh về khối lượng công việc cũng như trình độ mà các bạn cần đạt được thì anh nghĩ ít nhất cần 3 năm để đạt được vị trí Senior.

Trong 3 năm đó thứ nhất là để các bạn tích lũy kinh nghiệm làm việc thực tế trong các dự án và để học các kiến thức liên quan. Nên anh nghĩ là sẽ không có shortcut – lối tắt để chỉ sau 1 – 2 năm đã trở thành Senior được. Và khi các bạn Junior vào thì các bạn cũng phải học rất nhiều để nắm vững những framework đó. Để đạt được vị trí Senior thì anh nghĩ mình phải luôn đặt ra những mục tiêu học là những nền tảng của Front-end, về những cái cản bản nhất của JavaScript, CSS.

Như anh đề cập có một số bạn vẫn ở vị trí Junior dù đã đi làm một thời gian khá là lâu anh nghĩ là do các bạn chưa có tinh thần học hỏi, các bạn chỉ đến công ty và làm các task được giao mà thôi. Ở công ty thì các bạn sẽ làm trực tiếp các tính năng và các phần được giao, công việc này phần nào đó sẽ lặp đi lặp lại cho nên để mình có thể tiến xa hơn, hiểu sâu hơn thì bắt buộc các bạn nên tự học thêm về nó.

Có một tip anh rút ra được là dù mình làm ở những cấp độ cao – highlevel nhưng mình vẫn phải luôn đặt ra câu hỏi cách hoạt động của nó như thế nào, research để tìm hiểu cách hoạt động bên dưới của nó. Khi có cái mình thấy hay, thấy tò mò về cách hoạt động thì phải luôn luôn đi tìm hiểu nó và đó cũng là cách để mình có những kiến thức nền tảng cho mình. Qua thời gian mình sẽ có đủ kiến thức và khả năng đạt được vị trí Senior.

Rất cảm ơn những chia sẻ hết sức thiết thực của anh Trần Trọng Thanh. Hy vọng qua bài phỏng vấn lần này, các bạn độc giả sẽ có được những lựa chọn phù hợp cho bản thân. Chúc các bạn đạt nhiều thành công trong cuộc sống.

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

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