Home Blog Page 106

Lập trình web là làm gì? Cơ hội nghề nghiệp và mức lương?

Web Developer

Lập trình web (Web Developer) luôn nằm trong top những công việc được trả lương hấp dẫn. Điều này đến từ nhu cầu thị trường của ngành nghề này, bởi bất kỳ một doanh nghiệp nào nếu muốn tiếp cận với khách hàng tốt hơn đều cần phải xây dựng website chuyên nghiệp. Vậy chính xác công việc lập trình web là làm gì? Cần học gì để trở thành một lập trình web giỏi? Cùng TopDev tìm hiểu trong bài viết này nhé!

Lập trình web là làm gì?

Lập trình web là những người nhận ý tưởng thiết kế trang web và bắt đầu xây dựng chúng bằng cách sử dụng các ngôn ngữ lập trình như CSS, JavaScript, PHP, Python,… Các website được tạo ra cần đảm bảo tương tác với cơ sở dữ liệu và tương tác với người dùng dựa trên ngôn ngữ máy tính.

Lập trình web là làm gì?

Phân loại và nhiệm vụ của Web Developer

Công việc Web Developer được chia ra làm 3 nhánh: Front-end developer, Back-end developer và Full-stack developer. Mỗi vị trí sẽ đảm nhiệm một công việc cụ thể.

Front-end developer

Front-end developer là người phát triển phần giao diện người dùng của trang web. Họ sử dụng các ngôn ngữ lập trình như HTML, CSS và JavaScript để tạo ra các trang web tương tác, thân thiện với người dùng.

Công việc của Front-end developer bao gồm thiết kế giao diện, xây dựng và bảo trì các trang web, đảm bảo tính tương thích giữa các trình duyệt khác nhau và cải thiện trải nghiệm của người dùng. Front-end developer cũng phải có hiểu biết về các công cụ và kỹ thuật thiết kế, như Adobe Photoshop, Sketch, Figma, CSS Frameworks, Responsive Design, để có thể thiết kế giao diện đẹp và dễ sử dụng cho người dùng.

Back-end developer

Back-end developer là những người chuyên về phát triển phần mềm và cơ sở dữ liệu cho các trang web. Các back-end developer thường sử dụng những ngôn ngữ lập trình như Ruby, Python, PHP, Java, C# và Node.js để xây dựng các ứng dụng web và hệ thống quản lý cơ sở dữ liệu.

Công việc của back-end developer bao gồm thiết kế và xây dựng cơ sở dữ liệu, phát triển các API (Application Programming Interface), xây dựng phần mềm server-side bằng cách sử dụng backend frameworks, bảo mật thông tin, quản lý truy cập và đảm bảo tính ổn định, tốc độ của các trang web.

  Phát triển web nhờ các nguồn thông tin miễn phí sao cho hiệu quả?

  Tiêu chuẩn Coding Backend hiệu quả là gì

Full-stack developer

Full-stack developer là người có khả năng thành thạo các công việc của Front-end developer và Back-end developer. Điều này có nghĩa là họ có thể làm việc với giao diện người dùng, cơ sở dữ liệu và các yếu tố khác của một trang web. Full-stack developer có khả năng đảm nhiệm các công việc của cả Front-end và Back-end developer, từ thiết kế giao diện người dùng, xây dựng ứng dụng, tạo API, quản lý cơ sở dữ liệu đến triển khai và bảo trì hệ thống.

Công việc của các lập trình viên Full-stack sẽ có sự khác nhau tùy vào từng doanh nghiệp, đơn vị hoạt động. Tuy nhiên, hầu hết Full-stack developer đều đã có nhiều năm kinh nghiệm ở các vai trò khác nhau, họ sẽ có nền tảng vững chắc trong toàn bộ phạm vi phát triển trang web. Công việc của họ sẽ liên quan đến việc tạo và đảm bảo thiết kế trang web tốt, kiểm tra và khắc phục các sự cố phần mềm nhằm nâng cao hiệu quả, quản lý cơ sở dữ liệu và các công việc liên quan khác.

Tham khảo việc làm Web Developer hấp dẫn trên TopDev!

Những kỹ năng cần có của một lập trình web

Những kỹ năng cần có của một lập trình web

Nếu bạn đang muốn trở thành một lập trình web, thì dưới đây là một số kỹ năng bạn nên có để có thể thành công trong sự nghiệp.

Kỹ năng chuyên môn

  • Kiến thức về lập trình: Kiến thức về lập trình là cần thiết cho một Web Developer để có thể hiểu và viết mã lập trình. Bạn cần học và thành thạo các ngôn ngữ lập trình như HTML, CSS, JavaScript, PHP, Python, Ruby,…
  • Kiến thức về thiết kế giao diện người dùng (UI): Người dùng có thể sử dụng nhiều thiết bị khác nhau để xem trang web, bạn cần thiết kế giao diện trang web tương thích với mọi thiết bị thông minh.
  • Kiến thức về cơ sở dữ liệu: Web Developer cần phải hiểu cách thiết kế và quản lý cơ sở dữ liệu để lưu trữ thông tin cho trang web.
  • Kiến thức về SEO: Nhiều yếu tố của thiết kế trang web có thể ảnh hưởng đến xếp hạng công cụ tìm kiếm của trang web. Vì vậy, Web Developer cần có kiến thức về các kỹ thuật SEO để tối ưu hóa các trang web của họ.

Kỹ năng mềm

  • Kỹ năng giao tiếp và làm việc nhóm: Web Developer thường phải làm việc với các nhóm khác trong công ty hoặc với khách hàng. Vì vậy, kỹ năng giao tiếp và làm việc nhóm là rất quan trọng.
  • Kiến thức về các công nghệ mới: Web Developer cần phải cập nhật các công nghệ mới nhất để đáp ứng nhu cầu của khách hàng và đảm bảo rằng các trang web của họ luôn đáp ứng được tiêu chuẩn mới.
  • Khả năng giải quyết vấn đề: Web Developer cần phải có khả năng phân tích và giải quyết các vấn đề liên quan đến trang web của họ, đồng thời có thể đưa ra giải pháp và sửa chữa các lỗi kỹ thuật.
  • Tư duy sáng tạo: Một Web Developer cần có tư duy sáng tạo để thiết kế và phát triển các trang web độc đáo và hấp dẫn.

Mức lương và cơ hội nghề nghiệp của lập trình web

Mức lương của lập trình web thường được tính dựa trên nhiều yếu tố, bao gồm kinh nghiệm, vị trí, kỹ năng và nơi làm việc. Tuy nhiên, theo báo cáo thị trường IT 2022 của TopDev, mức lương của Web Developer theo từng vụ trí (Frontend, Backend, Fullstack) dao động trong khoảng $950 – $1.500 cho người tối đa 3 năm kinh nghiệm.

Cơ hội nghề nghiệp của Web Developer cũng rất lớn, vì vị trí này luôn thiếu nhân lực. Từ các công ty, doanh nghiệp nhỏ đến các tập đoàn lớn, đều có nhu cầu tuyển dụng Web Developer để phát triển và duy trì trang web của mình. Với kinh nghiệm lập trình web, bạn có thể trở thành chuyên gia về một lĩnh vực cụ thể như thiết kế giao diện người dùng, tối ưu hóa SEO cho web hoặc xây dựng website chuyên nghiệp.

Hy vọng bài viết này đã giúp bạn hiểu hơn về lập trình web là làm gì? Và những kỹ năng cần có của một Web Developer. Bạn có thể truy cập vào trang việc làm của TopDev để biết thêm thông tin về yêu cầu việc làm và mức lương của Web Developer trên thị trường hiện nay nhé. Chúc bạn thành công!

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

Tìm việc làm IT mới nhất trên TopDev

Cài đặt ConfigServer Security and Firewall (CSF) và Webmin trên CentOS 7

Cài đặt ConfigServer Security and Firewall (CSF) và Webmin trên CentOS 7

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

Sau loạt server của mình bị bọn bullshit tàn phá tơi tả dùng mail server của mình thành công cụ spam của bọn nó còn cố gắn hack quyền root của mình thông qua ssh và cũng vì chủ quan không có firewall nên phải tăng cường phòng thủ trước tiên xây dựng firewall ngăn chặn các đợt tấn công vào các port thông dụng như 22, 80,… Trình bài trước các technical cơ bản mà mình sử dụng để phòng thủ tụi nó.

  Cài đặt Elasticsearch trên CentOS
  Giới thiệu và hướng dẫn về FirewallD trên CentOS 7

ConfigServer Security and Firewall (CSF) là một firewall rất phổ biến và hiệu quả được sử dụng trên các server Linux hiện nay. Bên cạnh những tính năng cơ bản như một firewall, CSF còn có những chức năng bảo mật nâng cao khác như ngăn chặn flood login, port scans, SYN floods…

Webmin là ứng dụng quản lý server thông qua giao diện Web, đây là một ứng dụng nhẹ với nhiều tính năng cần thiết cho những nhà quản trị server. Vi dụ, bạn có thể thiết lập mọi thông tin về tài khoản người dùng, Apache, Dns ,chia sẻ file và nhiều hơn thế nữa. Để cài đặt webmin phiên bản mới nhất vào http://www.webmin.com/

Cài đặt CSF

Install CSF

Stop and disable firewalld.

systemctl disable firewalld
systemctl stop firewalld

Install iptables.

yum -y install iptables-services

Create files needed by iptables.

touch /etc/sysconfig/iptables
touch /etc/sysconfig/iptables6

Start iptables.

systemctl start iptables
systemctl start ip6tables

Enable iptables at boot.

systemctl enable iptables
systemctl enable ip6tables

Install the CSF dependencies.

yum -y install wget perl unzip net-tools perl-libwww-perl perl-LWP-Protocol-https perl-GDGraph -y

Download and launch the CSF installer.

cd /opt
wget https://download.configserver.com/csf.tgz
tar -xzf csf.tgz
cd csf
sh install.sh

Remove the installation files.

rm -rf /opt/csf rm /opt/csf.tgz

Tới bước này là có thể cấu hình dùng CSF ra trận dc rồi, mà mình lười quá làm cấu hình trên UI cho tiện nên dùng Webmin cài module của CSF vào cấu hình trên đó luôn. Nếu ai đã cài webmin rồi thì làm tiếp bên dưới còn chưa thì xem cách cài đặt webmin tại đây.

*** Lưu ý sau khi cài đặt webmin rồi truy cập https://server.com:10000

Đăng nhập vào webmin Webmin > Webmin Configuration > Webmin Modules

Click “From local file” and insert the following.

/usr/local/csf/csfwebmin.tgz

Sau đó tiến hành cấu hình và bật firewall để phòng thủ ngay. Sau đây là cấu hình cơ bản nhanh gọn, mọi người có thể cấu hình thêm để tăng security.

config-csf

Sau đó click button “Change” để restart csf+lfd. Vậy là done.

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

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

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

Tại sao phải dùng CARD ĐỒ HỌA để nghiên cứu AI?

Tại sao phải dùng CARD ĐỒ HỌA để nghiên cứu AI?

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

AI (Trí tuệ nhân tạo) đã và đang ngày càng trở thành một thứ không thể thiếu trong sự phát triển của công nghệ ngày nay. Đi cùng với sự phát triển đó là hoạt động nghiên cứu AI ngày càng nở rộ hơn ở khắp nơi trên thế giới !

Không chỉ có những trung tâm nghiên cứu lớn mới có thể nghiên cứu AI nữa, mà ngay cả những doanh nghiệp vừa và nhỏ hiện nay cũng hoàn toàn đủ sức để nghiên cứu và phát triển AI.

  "Làm PM, theo anh không cần biết về code, nhưng phải hiểu về SQL, database, những khái niệm cơ bản của code"
  "Vì sao mình chọn start-up sau Facebook?" Hiếu Phạm - Software Engineer tại ROCKSET

Ngoài vấn đề về nhân lực ra thì vấn đề về phần cứng để phục vụ cho công việc nghiên cứu này cũng đang ngày được phổ thông hóa hơn. Cụ thể là các card đồ họa cao cấp ngày nay đã tập trung và hỗ trợ cho việc nghiên cứu AI nhiều hơn…

Vậy bạn có bao giờ tự hỏi, tại sao các card đồ họa ngày càng được dùng nhiều trong lĩnh vực nghiên cứu AI không? Vâng, nếu bạn cũng đã từng thắc mắc như vậy thì hôm nay, chúng ta hãy cùng tìm hiểu về vấn đề này nhé.

#1. Khái niệm cơ bản về AI

vi-sao-phai-dung-card-do-hoai-de-nghien-cuu-ai (1)

Tên đầy đủ của AI là Artificial Intelligence – trí thông minh nhân tạo.  Về cơ bản thì đây là một chương trình do con người lập trình nên, kết hợp với Machine Learning (Học máy – lĩnh vực nghiên cứu) để tạo ra một AI hoàn chỉnh.

Thông thường, AI hoạt động dựa trên khối dữ liệu mà nhà lập trình nạp vào => sau đó nó dựa vào khối dữ liệu mà nó có được để đưa ra các thông tin, trả về kết quả tương ứng với mỗi trường hợp khác nhau.

Nghĩa là không có sự thần thánh gì ở đây cả, gần như những gì mà AI hiện tại làm được là nhờ vào những gì mà con người nạp vào cho nó. Hiển đơn giản vậy thôi các bạn !

vi-sao-phai-dung-card-do-hoai-de-nghien-cuu-ai (4)

#2. Để nghiên cứu AI cần những gì?

Đầu tiên mình xin khẳng định, yếu tố cốt lõi nhất vẫn là con người. Thật vậy đấy, những trung tâm nghiên cứu AI cần phải có một đội ngũ nhân lực có trình độ cao về công nghệ thông tin (IT).

Ngoài đội ngũ lập trình chuyên môn cao ra, việc nghiên cứu AI còn cần đến các chuyên gia trong lĩnh vực máy học, xã hội học, thậm chí là con người học… nói chung là các loại học.

Bởi AI là trí tuệ nhân tạo, nó được tạo ra để làm những việc như con người, vậy nên những yếu tố như xã hội, hành vi con người đều phải được quan tâm và nó là nguồn dữ liệu quan trọng cho AI.

vi-sao-phai-dung-card-do-hoai-de-nghien-cuu-ai (5)

Thứ hai, tất nhiên rồi – đó là máy móc. Chắc hẳn chúng ta đã không ít lần nghe những câu chuyện về những thanh niên một mình, cùng với một chiếc máy tính cá nhân có thể viết ra cả một phần mềm đáng giá cả triệu đô.

Nhưng AI thì khác, nó có sự phức tạp và nguồn dữ liệu vô cùng lớn nên sẽ rất khó để một cá nhân có thể tự làm hoàn chỉnh được.

Và những chiếc máy tính phục vụ cho việc nghiên cứu AI luôn là những cỗ máy có cấu hình rất khủng và đặc biệt thường đi kèm đó là 3 – 4 card đồ họa cao cấp.

#3. Tại sao chọn GPU (card đồ họa) để nghiên cứu AI?

Đơn giản bởi vì GPU có khả năng xử lý các dữ liệu song song cùng lúc tốt hơn so với CPU !

Như mình đã nói ở trên, AI vốn là sự suy đoán từ nguồn dữ liệu nạp vào, vậy nên khối lượng công việc mà nói phải làm là rất “khổng lồ”, trong khi đó nó lại không cùng một hoạt động.

Chúng ta có một ví dụ về AI phân biệt màu sắc: dữ liệu nạp vào là những đặc điểm về màu, cụ thể là tính chất quang học của nó chẳng hạn.

Khi hệ thống phần cứng ghi lại hình ảnh màu sắc phía trước, lúc này nhờ vào những gì cảm biến thu nhận được thì AI sẽ bắt đầu so sánh với dữ liệu mình có được => và tiến hành đưa ra kết quả. Cách thức hoạt động này cũng tương tự với các hệ thống AI khác.

vi-sao-phai-dung-card-do-hoai-de-nghien-cuu-ai (2)

So sánh với ví dụ, có thể thấy khối lượng công việc khổng lồ là  các đặc tính vật lý thu nhận được trên camera hay cảm biến, còn hoạt động chỉ là so sánh với dữ liệu mà nó có => sau đó thì đưa ra kết quả.

Tiếp theo nữa, với các card đồ họa cao cấp hiện nay, bộ nhớ Ram có dung lượng rất lớn và tốc độ là cực kì cao. Có thể kể đến card đồ họa RTX 3090 thuộc hàng TOP trên thị trường hiện nay với dung lương là  24GB GDDR6X, đi cùng với Bus là: 384-bit và Bandwidth (băng thông): 936 GBps.

Đây là một thông số rất ấn tượng, nó bảo đảm cho những dữ liệu lớn không bị delay và mọi thứ được xử lý một cách nhanh nhất có thể.

Một yếu tố không thể không kể đến nữa là sự hậu thuận từ các nhà sản xuất với việc thiết kế những nhân chuyên biệt bên trong card đồ họa.

Gần đây nhất là nhân Tensor Core của Nvidia được chuyên biệt cho khả năng làm việc Deep Learning (một nhánh sâu hơn của Machine Learning).

vi-sao-phai-dung-card-do-hoai-de-nghien-cuu-ai (3)

Những cải tiến này giúp cho máy học trong vài tháng, nay chỉ còn vài tuần theo như những gì mà Nvidia công bố. Rút ngắn rất nhiều thời gian !

Vâng, như vậy là qua bài viết này thì chúng ta đã trả lời được cho câu hỏi: Tại sao các card đồ họa thường được dùng để nghiên cứu AI nhiều hơn là CPU rồi nhé.

Tuy nhiên, nhiều chuyên gia họ đang thử nghiệm phát triển những cấu trúc lệnh mới trong nghiên cứu AI để nó có thể chạy tốt hơn trên CPU, bởi theo họ CPU về cơ bản có hiệu quả kinh tế tốt hơn.

Lê Đinh Hoàng Vũ – Bài viết gốc tại blogchiasekienthuc.com

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

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

Giao tiếp giữa Tester và Dev

tester vs dev

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

Chào các bạn,

Sau một thời gian “chinh chiến” với Dev thì bản thân mình nhận thấy “À, hóa ra sự việc cũng không đến nỗi tệ như thế”.

Tuyển dụng tester lương cao trong tháng cho bạn

Trong công việc hằng ngày của một tester thì giao tiếp với dev là một việc khó khăn mà có khá nhiều bạn mới vào nghề đều kêu “Ôi nản quá ạ”. Cá nhân mình làm gần 3 năm cũng nhiều lúc máu lên não không kịp nên cãi nhau với dev là điều khó tránh khỏi :))…….. May mắn là các bạn Dev đều sàn sàn tuổi mình, có người thì thấp hơn và cũng đanh đá y như mình nên việc nói chuyện với mình dễ thở hơn.:D:D:D……… Có những lúc 2 bên hiểu khác requirement của khách hàng, tester hiểu một kiểu, dev hiểu một kiểu, đến lúc thảo luận thì mỗi bên đều bảo vệ ý kiến của mình, ai cũng nghĩ là mình đúng, những lúc thế này, tranh luận nghiêm túc và chịu lắng nghe đối phương nói là phương pháp hữu ích nhất, khi mà tranh luận ko đi đến hồi kết thúc thì chúng ta nên note lại ý hiểu và QA lại với khách hàng xem bên mình đang có 2 ý hiểu thế này, có ý nào đúng không? Việc đặt câu hỏi với khách hàng cũng tránh việc hỏi lan man, mà nên đặt những câu ngắn gọn, dễ hiểu nhất có thể, nên đưa ra ý hiểu của mình trước, chứ không nên đặt các câu đại loại như “cái này bên em đang không hiểu làm thế nào, có thể giải thích cho chúng em không?”, thay vì hỏi vậy, các bạn nên hỏi “Với ý này bên em đang hiểu là abcxyz, nhờ anh chị confirm lại giúp em xem đã đúng chưa?”, theo mình cách đặt QA rất quan trọng, thế nên mọi người cần chú ý tránh việc lan man dài dòng.

handshake

Quay trở lại với việc giao tiếp, trò chuyện với dev. Có nhiều khi, mình gặp trường hợp mình test ra bugs, nhưng dev cứ khăng khăng đó không phải là bugs. Lúc này lại một lần nữa ngồi tìm lại require or các mail confirm của dự án về vấn đề đó để xem bên nào đang đúng, đang sai. Cho dù lúc này mình có đúng thì cũng nên giải thích nhẹ nhàng với dev, tránh việc làm căng thẳng vấn đề. Ngược lại, mình sai thì chấp nhận một cách “Ừ nhở, mình sai, mình hiểu thêm vấn đề rồi”, tất cả những việc này đều nhằm mục đích nâng cao chất lương của sản phẩm thế nên nó là chuyện hết sức bình thường trong công việc…….. Dự án mình có đội dev khá dễ chịu, nên tính cách của mình có “điên” thế nào chúng mình vẫn tranh luận khá sôi nổi và đều kết thúc êm đẹp, may là chưa lần nào 2 bên giận lâu quá 1h :))

Có một câu chuyện mình từng chứng kiến ở dự án thế này, khi sắp đến giai đoạn release sản phẩm cho khách hàng, dự án đang bị “Cháy” nên có khá nhiều bugs, đội dev OT, ON liên miên, gần đến này release, có 1 anh ngồi chơi game nhiều quá bỏ bê cả việc fix bugs, hồi đó có 1 em tester mới vào làm, em ý thái độ với anh kia, cái bị anh ý mắng và dỗi không fix bugs nữa, xong bugs đó report cho khách hàng và xin phép để phase tiếp theo sẽ fix, em tester và a dev sau 1 tháng mới nói chuyện lại với nhau, nhưng sau vụ đấy em ý khóc hết nước mắt và vài cuộn giấy :P. Qua việc này, thì mình thấy việc nói chuyện với dev mềm mỏng và nhẹ nhàng khá quan trọng, ở đây chưa nói đến việc PM có trách nhiệm gì hay cần làm gì, mà cái mình thấy rõ nhất, nếu như quan hệ giữa tester và dev căng thẳng thì công việc sẽ không mang lại hiệu quả cao nếu chưa muốn nói là sẽ bị chậm tiến độ, ảnh hưởng đến dự án, uy tín và không làm hài lòng khách hàng.

Trên thực tế có khá nhiều chuyện củ chuối nữa, nhưng dù sao thì mỗi lần như vậy sẽ cho mình thêm kinh nghiệm, thế nên mọi người đừng ngại ngùng, cứ thoải mái sẽ tích lũy được kinh nghiệm, mình lại đi “cãi nhau” với dev tiếp đây, hẹn gặp các bạn ở bài sau nha :P:P:P

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

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

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

Hướng dẫn cài đặt ClamAV trên Linux để quét virus/malware/trojan

Hướng dẫn cài đặt ClamAV trên Linux để quét virus/malware/trojan

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

Khi Server bị nhiễm virus/trojan/malware bởi các thành phần như source website, mã nguồn chương trình lạ,… thì làm sao để phát hiện và xử lý chúng?

  10 điều bạn có thể làm với Linux mà bạn không thể làm với Windows
  5 lý do lập trình viên nên sử dụng hệ điều hành Linux

ClamAV là gì ?

ClamAV là một engine (core phần mềm) mã nguồn mở chuyên dụng để phát hiện trojans, virus, malware và các mối hiểm hoạ khác.

Trang chủ : https://www.clamav.net

Tất nhiên là đối với các chương trình AntiVirus thì chúng đều phụ thuộc vào cơ sở dữ liệu chứa những dấu hiệu nhận biết (signature/checksum) về virus,… ta không nên đặt niềm tin hoàn toàn vào chúng. Cũng vì phụ thuộc nhiều vào CSDL nên chúng ta cần thường xuyên cập nhật CSDL của các chương trình mang danh Anti-Virus.

ClamAV có thể kết hợp với nhiều dịch vụ khác và mình sẽ đề cập sau này. Ở bài này, chúng ta đơn giản chỉ cài đặt và sử dụng đơn giản chức năng của nó.

Vậy ta sẽ tiến hành cài đặt ClamAV trên Linux như CentOS hay Ubuntu.

1. Cài đặt ClamAV trên Linux

Có hai hình thức để cài đặt chương trình ClamAV trên Linux là :

  • Cài đặt từ Repository của OS
  • Biên dịch mã nguồn source ClamAV

1.1 Cài đặt ClamAV từ Repository CentOS hoặc Ubuntu

Bạn sẽ tiến hành cài đặt ClamAV thông qua chương trình ‘yum‘ trên CentOS/RHEL hoặc ‘apt-get‘ trên Debian/Ubuntu.

+ Centos/RHEL

#yum install -y clamav-server clamav-server-systemd clamav-scanner-systemd clamav-data clamav-update clamav-filesystem clamav clamav-devel clamav-lib

+ Debian/Ubuntu

2. Khởi động dịch vụ ClamAV

Thông thường ClamAV chỉ dùng cho hoạt động quét bình thường. Nhưng khi kích hoạt cơ chế dịch vụ, ClamAV sẽ được load lên bộ nhớ RAM và các dịch vụ khác có thể truy cập port dịch vụ ClamAV để sử dụng tính năng quét virus cho nhanh.

Dịch vụ ClamAV (clamd hoặc clam-daemon), thường được sử dụng trong các hoạt động nâng cao như quét virus trong các email incomming. Vậy ta có cần khởi động dịch vụ này không?! Câu trả lời là không, nếu bạn không xài tính năng nâng cao kết hợp. Nhưng làm sao để khởi động dịch vụ này?

+ Init system (CentOS/RHEL 6 Ubuntu 14.04)

# /etc/init.d/clamd start
# chkconfig clamd on

+ Systemd system (CentOS/RHEL 7 Ubuntu 16.04

# systemctl start clamd
# systemctl enable clamd

3. Cập nhật các cơ sở dữ liệu mẫu Virus

Như đã trình bày ở đầu bài, thì bạn cần thường xuyên update CSDL chứa các mẫu nhận diện virus/malware thì ClamAV mới có thể quét phát hiện chúng.

Các file CSDL update sẽ được lưu tại:

4. Tiến hành sử dụng ClamAV Scan Virus

Clamscan’ là chương trình binary chính của ClamAV sử dụng để quét mã độc. Để coi các option sử dụng của ‘clamscan‘ bạn hãy dùng option ‘–help‘.

ClamAV có thể scan một hay nhiều file chỉ định hoặc scan cả một thư mục quy định.

Chú thích:

  • –infected hoặc -i: chỉ in output các file bị cho là nhiễm mã độc.
  • –recursive hoặc -r: scan cả các thư mục hay file phía trong thư mục cha.
  • –remove=[yes/no]: xoá luôn các file bị nghi nhiềm mã độc tìm thấy.
  • –no-summary: không in ra nội dung tổng kết.
  • –log=/file.log: ghi log scan vào file cụ thể.
  • –mv=/path: di chuyển tất cả file bị nghi là nhiễm mã độc đến thư mục khác.

5. Tải về một mẫu thử Virus

Đây là một mẫu thử chỉ chứa dấu hiệu (signature) phổ biến không tồn tại mã độc nào hết.

wget -O- http://www.eicar.org/download/eicar.com.txt | clamscan -
stdin: Eicar-Test-Signature FOUND
  • clamscan –: tức là bạn sẽ scan một stream lấy output trước đó làm input mẫu sẽ scan.

Các bạn có thể viết một shell script để tự động quét virus vào một thời điểm cụ thể nào đấy trong ngày bằng dịch vụ “cron” .

6. Cấu hình cronjobs ClamAV

Để thực hiện cấu hình cho hệ thống quét malware theo thời gian định kì cronjob thì ta làm như sau:

# crontab -e
0 0 * * * clamscan --recursive=yes --infected /home/

Với nội dung cấu hình cronjob trên thì cứ mỗi ngày vào lúc 00 giờ sáng, chương trình ClamAV sẽ tiến hành quét malware, trojan ở thư mục /home/

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

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

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

Cơ bản về kiểm thử API

Cơ bản về kiểm thử API

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

Sau buổi offline với club Testingvn về chủ đề API testing với Jmeter, mình rất có hứng thú với chủ đề này, nhưng lại chưa có nhiều kinh nghiệm sử dụng Jmeter và mình quen dùng Postman hơn (dễ cài dặt, giao diện dễ nhìn và cũng mạnh mẽ không thua kém là mấy). Chủ đề này mình sẽ cố gắng viết ngắn gọn khoảng 2-3 bài để không bị kéo dài lan man, còn tất nhiên là có kết thúc được hay không thì không biết. :))))))

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

API là gì?

kiểm thử apiNói đơn giản, API là cái cầu nối giữa client và server. Client ở đây có thể là máy tính, điện thoại sử dụng hệ điều hành khác nhau và được viết bằng những ngôn ngữ khác nhau. Tương tự, server back-end cũng được viết bằng các ngôn ngữ khác nhau. Để 2 thằng này có thể nói chuyện được với nhau chúng phải nói cùng 1 ngôn ngữ. Ngôn ngữ ấy chính là API.

Chúng ta hãy lấy một ví dụ đơn giản cho vấn đề này : Giả sử bạn là 1 người hướng dẫn viên du lịch, và quản lý 1 nhóm du lịch hợp chủng quốc. Trong nhóm có người Nga, Mỹ, Nhật, Thụy Điển, Đức, Pháp, Việt Nam. Để có thể làm mọi việc một cách suôn sẻ, tất cả cái nhóm này phải cùng nói 1 ngôn ngữ, có thể là tiếng anh hoặc tiếng Việt. Ở đây người hướng dẫn viên sẽ đóng vai trò là Server, người du lịch sẽ đóng vai trò là client.

Khi đi trên đường hoặc đến thăm địa danh du lịch, những người khách có thể hỏi hướng dẫn viên “Cái kia là gì ?”,  “Ăn quả này như thế nào?”.. Với mỗi một hành động hỏi như vậy, tương ứng với việc gửi 1 request lên server với những tham số đầu vào như “Cái kia” hay “quả này”. (Gửi request còn được gọi là Call API). Với mỗi câu hỏi, người hướng dẫn viên sẽ trả lời 1 cách khác nhau – cái này gọi là response. “Cái đó là cái để đập vào đầu những đứa nào hỏi nhiều”, “Quả này cứ cho vào mồm là xong”. :)))

Client server

Định dạng trong việc hỏi và trả lời ở trên có thể thông qua trò chuyện trực tiếp hoặc viết giấy. Ở trong API thì có 2 định dạng chính là xml và json. Hiện tại, mình chỉ có kinh nghiệm với json nên chỉ giới thiệu và lấy ví dụ ở những bài sau bằng json thôi.

Vì sao phải test API?

Trong quá trình triển khai dự án, phần server và client làm độc lập với nhau nên có nhiều chỗ client chưa làm xong, mình không thể chờ client làm xong để test được dữ liệu mà test API bằng công cụ khác luôn –> Lúc này việc test hoàn toàn không phụ thuộc gì vào client.

Kể cả khi client làm xong rồi, nếu mình test trên client mà thấy lỗi liên quan đến logic và dữ liệu thì cũng cần test thêm cả API để biết chính xác là server sai hay client sai –> fix lỗi sẽ nhanh hơn.

Khi làm hệ thống web services, dự án của mình chỉ viết API cho bên khác dùng, mình sẽ không có client để test giống như các dự án khác –> phải test API hoàn toàn.

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

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

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

Các trường hợp kiểm thử cho trường nhập Ngày tháng năm (Date field)

Các trường hợp kiểm thử cho trường nhập Ngày tháng năm (Date field)

Bài viết được sự cho phép của tác giả To Thi Van Anh

Trường dữ liệu nhập thông tin liên quan đến ngày tháng năm là một trong những trường thông tin vô cùng phổ biến trong rất nhiều các ứng dụng từ xưa đến nay, và chưa có dấu hiệu là sẽ biến mất đâu nhé! 😀 Thông tin này nó liên quan trực tiếp đến các hoạt động trong cuộc sống hàng ngày của chúng ta như Ngày sinh, Ngày mất, Ngày đăng ký, Ngày nhập học, Ngày cấp bằng, Ngày cấp CCCD, … Bất kể thông tin nào được công nghệ hóa quản lý thì đều phải được nhập vào, do đó sự hiện diện của nó trong các ứng dụng là điều đương nhiên rồi ;))

  10 bước để bắt đầu áp dụng kiểm thử tự động vào dự án
  11 công cụ hữu ích để kiểm tra và tối ưu hóa các file CSS

Hiện nay hầu hết các ứng dụng mà có nhập trường Ngày này thì thông tin dữ liệu đều được chọn từ một Calendar có sẵn khi người dùng click vào trường đó. Calendar này được deverloper sử dụng từ framework có sẵn, nó cũng rất là thuận tiện cho người dùng khi mà chỉ cần một vài cú nhấp chuột là chọn xong thông tin cần nhập. Vậy thì ở đó có thể xảy ra các lỗi gì mà các tester cần phải lưu ý tránh lọt lỗi đây nhỉ. Cùng mình tìm ra các test case cho trường này trong bài viết này nhé!

Đầu tiên, cùng đưa ra các kiểu nhập dữ liệu ngày tháng năm đã nào.

Hiện nay trường nhập Date phổ biến theo mình biết là kiểu dưới này: Khi click vào textbox thì lập tức hiển thị Calendar. Có thể nhập thông tin bằng cách chọn từ Calendar đó hoặc nhập trực tiếp ngày tháng theo định dạng vào textbox đó cũng được.

Hình 1

Cũng hiển thị Calendar, nhưng lại có cách thiết kế hiển thị khác nhau như tách riêng thông tin tháng và năm ra mà không gộp lại như hình bên trên nữa, kiểu như này:

Hình 2

Một kiểu khác lâu lắm mới gặp ứng dụng web nào sử dụng nữa đó là tách biệt các trường Ngày, Tháng, Năm ra, nhưng cái này có thể gặp ở các ứng dụng trên di động nhé 🙂 nó kiểu như dưới này, có thể đâu đó do nhu cầu lưu trữ dữ liệu, hoặc thiết kế gì đấy mà người ta sẽ thiết kế kiểu như này:

Hình 3

Trong khuôn khổ bài viết này thì mình sẽ bám sát vào giao diện đầu tiên nhé. Dưới đây là danh sách các trường hợp cần phải kiểm tra, các bạn cùng tham khảo và nếu có ý kiến đóng góp thì cùng bổ sung với mình nha:

  1. Kiểm tra việc hiển thị của Calendar khi click vào textbox của trường. 
  2. Kiểm tra kích thước của Calendar khi hiển thị lên phải đúng như mô tả trong tài liệu.
  3. Kiểm tra kích thước hiển thị của Calendar phải được hiển thị linh động và phù hợp (responsive) theo từng kích thước màn hình và thiết bị khác nhau.
  4. Kiểm tra trường hợp khi chọn ngày từ Calendar thì thông tin được chọn hiển thị đúng lên textbox. 
  5. Kiểm tra thông tin mặc định của Calendar khi hiển thị lên, có thể focus vào ngày – tháng – năm hiện tại.
  6. Kiểm tra khi click vào nút “Trước (<<)” “Sau (>>)” thì Calendar sẽ hiển thị đúng ngày của tháng trước và tháng sau tương ứng.
  7. Kiểm tra người dùng có thể thực hiện chọn tháng bất kỳ trong năm bất kỳ nào đó từ Calendar.
  8. Kiểm tra rằng người dùng có thể nhập trực tiếp thông tin ngày tháng vào textbox thay vì phải chọn từ Calendar.
  9. Kiểm tra định dạng (format) được hỗ trợ của trường này. VD: dd/mm/yy, mm/dd/yy, dd/mm/yyyy…
  10. Kiểm tra việc người dùng có thể thực hiện chỉnh sửa thông tin ngày tháng sau khi chọn từ Calendar.
  11. Kiểm tra việc hạn chế nhập các ký tự không phải là số, các ký tự đặc biệt, ngôn ngữ đặc biệt vào trường này (tất nhiên sẽ loại trừ trường hợp dấu ngăn cách / hoặc -)
  12. Kiểm tra đối với trường hợp nhập trực tiếp, không cho phép hoặc xử lý trường hợp nhập dữ liệu không hợp lệ như lớn hơn ngày 31, hoặc ngày 30 đối với tháng 2, rồi tháng lớn hơn 12…
  13. Kiểm tra trường hợp ngày tháng năm nhỏ nhất có thể nhập và chọn từ Calendar.
  14. Kiểm tra trường hợp ngày tháng năm lớn nhất có thể nhập và chọn từ Calendar.
  15. Kiểm tra giao diện hiển thị trong các trường hợp màn hình cực lớn và cực nhỏ khác nhau.
  16. Kiểm tra trong trường hợp textbox đã có dữ liệu khi click vào textbox đó sẽ hiển thị Calendar có thông tin mặc định lấy theo dữ liệu ở textox.

Bên cạnh các test case chung chung bên trên, ta cũng cần phải căn cứ vào mô tả, yêu cầu của hệ thống để bổ sung các test case cần thiết. Ví dụ như có thể trường cần yêu cầu kiểm tra bắt buộc hay không, có ràng buộc nào liên quan đến ngày hiện tại hay không, ràng buộc dữ liệu liên quan đến các thông tin khác trong hệ thống như Từ ngày, Đến ngày, ràng buộc liên quan đến độ tuổi..v..v…

Hi vọng bài viết đã mang đến cho các bạn góc nhìn nào đó liên quan đến việc kiểm thử trường dữ liệu này, nếu các bạn có ý kiến hoặc đóng góp thì thoải mái để lại phản hồi ở phần bình luận phía dưới cho mình nhé!

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

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

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

Top 10 Hệ quản trị cơ sở dữ liệu (DBMS) phổ biến

Danh sách 10 HỆ QUẢN TRỊ CƠ SỞ DỮ LIỆU tốt nhất !

Chào các bạn, đã từ lâu hệ quản trị cơ sở dữ liệu (Database Management System – DBMS) là một phần không thể thiếu trong các hệ thống thông tin có nhu cầu quản lý và trao đổi dữ liệu. Thậm chí là việc sử dụng hệ quản trị CSDL tốt và đúng cách còn rất quan trọng trong quá trình phát triển và mở rộng hệ thống.

Vậy nên, ở trong bài viết này TopDev sẽ cùng với các bạn tìm hiểu về hệ quản trị cơ sở dữ liệu và TOP 10 HỆ QUẢN TRỊ CƠ SỞ DỮ LIỆU đang được sử dụng rộng rãi nhất tính đến thời điểm hiện tại nhé!

Hệ quản trị cơ sở dữ liệu là gì?

Hệ quản trị cơ sở dữ liệu là gì?
Hệ quản trị cơ sở dữ liệu là gì?

Hệ quản trị cơ sở dữ liệu – Database Management System (DBMS) là một hệ thống được sử dụng để quản lý và điều hành cơ sở dữ liệu (CSDL). Bạn có thể thao tác thêm mới, sửa, xóa và truy vấn dữ liệu một cách hiệu quả và an toàn. DBMS đảm bảo dữ liệu được tổ chức tốt và dễ dàng truy xuất, đồng thời bảo mật dữ liệu và duy trì tính nhất quán.

Một số ứng dụng thực tiễn của DBMS trong doanh nghiệp

  • Quản lý Khách hàng (CRM – Customer Relationship Management): Các hệ thống CRM sử dụng DBMS để lưu trữ thông tin về khách hàng và tương tác của họ với công ty. Ví dụ như Salesforce sử dụng hệ quản trị cơ sở dữ liệu để lưu trữ thông tin khách hàng, lịch sử mua hàng, và dữ liệu liên quan để quản lý mối quan hệ khách hàng hiệu quả.
  • Hệ thống Quản lý Nhân sự (HRMS – Human Resource Management System): Các hệ thống quản lý nhân sự sử dụng DBMS để lưu trữ thông tin về nhân viên, bảng lương, quản lý thời gian làm việc và các dữ liệu nhân sự khác. Ví dụ như SAP ERP HR sử dụng hệ quản trị CSDL để quản lý thông tin nhân viên và quá trình tuyển dụng.
  • Hệ thống Quản lý Sản xuất và Tài nguyên (ERP – Enterprise Resource Planning): Các hệ thống ERP sử dụng DBMS để quản lý dữ liệu về quá trình sản xuất, vận hành kinh doanh, lưu trữ dữ liệu tài chính, và quản lý lô hàng. Ví dụ như Oracle ERP sử dụng hệ quản trị cơ sở dữ liệu để tích hợp các dữ liệu từ các phòng ban khác nhau của công ty.
  • Hệ thống Quản lý Kho (WMS – Warehouse Management System): Các hệ thống quản lý kho sử dụng DBMS để quản lý thông tin về vị trí hàng hóa trong kho, lượng tồn kho, và quản lý điều hành các quá trình nhập xuất hàng hóa. Ví dụ như Manhattan Associates sử dụng hệ quản trị cơ sở dữ liệu để quản lý và tối ưu hóa quá trình kho hàng.
  • Hệ thống Quản lý Tài chính (Financial Management System): Các hệ thống quản lý tài chính sử dụng DBMS để lưu trữ và quản lý dữ liệu tài chính, báo cáo tài chính, và quản lý chi phí. Ví dụ như QuickBooks sử dụng hệ quản trị cơ sở dữ liệu để lưu trữ thông tin tài chính và quản lý kế toán.

Cấu trúc của hệ quản trị cơ sở dữ liệu

Cấu trúc của một hệ quản trị CSDL bao gồm các thành phần chính sau đây:

Cấu trúc của hệ quản trị cơ sở dữ liệu
Cấu trúc của hệ quản trị cơ sở dữ liệu

Core DBMS Engine

Là trung tâm của hệ thống DBMS, chịu trách nhiệm xử lý các yêu cầu từ người dùng và quản lý dữ liệu. Nó bao gồm các module để phân tích và thực hiện các truy vấn SQL, xử lý các giao dịch, quản lý bộ nhớ và đọc/ghi dữ liệu vào bộ nhớ hoặc ổ đĩa.

Cơ sở dữ liệu (Database)

  • Bảng (Tables): Đây là thành phần chính trong cơ sở dữ liệu quan hệ (Relational Database). Mỗi bảng chứa dữ liệu có cấu trúc, được tổ chức thành các cột (fields) và hàng (rows). Mỗi cột đại diện cho một thuộc tính riêng biệt và mỗi hàng đại diện cho một bản ghi (record) cụ thể.
  • Mối quan hệ (Relationships): Đây là cách mà các bảng trong cơ sở dữ liệu liên kết với nhau thông qua các khóa ngoại (foreign keys) và khóa chính (primary keys). Mối quan hệ giúp cho việc truy xuất và thao tác dữ liệu giữa các bảng trở nên hiệu quả và logic.

Hệ quản trị cơ sở dữ liệu (DBMS)

  • Trình quản lý cơ sở dữ liệu (Database Manager): Là thành phần chịu trách nhiệm quản lý cơ sở dữ liệu, bao gồm các dịch vụ như lưu trữ, truy xuất, cập nhật, và bảo vệ dữ liệu. Trình quản lý cơ sở dữ liệu có thể hỗ trợ nhiều loại cơ sở dữ liệu khác nhau như quan hệ (Relational), đối tượng (Object), và các dạng khác.
  • Trình quản lý bảo mật (Security Manager): Đảm bảo rằng chỉ những người được cấp quyền mới có thể truy cập vào dữ liệu và thực hiện các thao tác. Quản lý bảo mật bao gồm xác thực người dùng, kiểm soát truy cập và mã hóa dữ liệu.
  • Trình quản lý dữ liệu (Data Manager): Xử lý các yêu cầu truy xuất dữ liệu từ người dùng và ứng dụng, đảm bảo rằng các truy vấn SQL được thực thi một cách hiệu quả và chính xác.
  • Trình điều khiển cơ sở dữ liệu (Database Driver): Là thành phần trung gian giúp các ứng dụng kết nối và giao tiếp với cơ sở dữ liệu. Điều khiển cơ sở dữ liệu thực hiện việc chuyển đổi giữa dữ liệu được lưu trữ trong cơ sở dữ liệu và dữ liệu được xử lý bởi ứng dụng.

Vùng lưu trữ (Storage Area)

  • File dữ liệu (Data Files): Đây là các tập tin vật lý hoặc phân vùng trên đĩa cứng được DBMS sử dụng để lưu trữ dữ liệu. Các bảng và dữ liệu trong cơ sở dữ liệu được lưu trữ trong các file này theo cấu trúc cụ thể của DBMS.
  • File nhật ký (Log Files): Được sử dụng để ghi lại các thay đổi dữ liệu và các hoạt động quản lý của hệ thống. Log files quan trọng trong việc phục hồi dữ liệu sau khi xảy ra sự cố và đảm bảo tính toàn vẹn của dữ liệu.

Người Sử Dụng (Users)

  • Người quản trị hệ thống (Database Administrators): Cài đặt và duy trì hệ thống cơ sở dữ liệu, quản lý bảo mật, và tối ưu hóa hiệu suất.
  • Lập trình viên (Developers): Phát triển ứng dụng và truy xuất dữ liệu từ cơ sở dữ liệu bằng các ngôn ngữ lập trình và truy vấn SQL.
  • Người dùng cuối (End Users): Truy xuất và thao tác với dữ liệu thông qua các ứng dụng được xây dựng trên nền tảng cơ sở dữ liệu.

Ứng Dụng (Applications)

  • Ứng dụng kinh doanh (Business Applications): Sử dụng dữ liệu từ cơ sở dữ liệu để hỗ trợ các quyết định kinh doanh và quản lý hoạt động.
  • Hệ thống phân tích dữ liệu (Analytics Systems): Phân tích và xử lý dữ liệu từ cơ sở dữ liệu để đưa ra các báo cáo, dự đoán và thống kê.

DBMS hoạt động ra sao?

DBMS hoạt động ra sao?
Hệ quản trị cơ sở dữ liệu hoạt động ra sao?
  1. Lưu trữ dữ liệu: DBMS quản lý cách dữ liệu được tổ chức và lưu trữ trong cơ sở dữ liệu. Dữ liệu thường được tổ chức dưới dạng bảng, trong đó mỗi bảng có các cột và hàng.
  2. Truy xuất dữ liệu: Người dùng có thể truy xuất dữ liệu từ cơ sở dữ liệu bằng các truy vấn SQL (Structured Query Language) để lấy thông tin cụ thể hoặc thực hiện tính toán trên dữ liệu.
  3. Cập nhật dữ liệu: DBMS cho phép người dùng cập nhật dữ liệu bằng cách thêm mới, sửa đổi hoặc xóa bỏ các bản ghi trong cơ sở dữ liệu.
  4. Quản lý bảo mật: DBMS bảo vệ dữ liệu bằng cách thiết lập quyền truy cập, mã hóa dữ liệu và xác thực người dùng.
  5. Quản lý hiệu suất: DBMS quản lý tối ưu hóa hiệu suất bằng cách tổ chức dữ liệu và tối ưu hóa các truy vấn để đảm bảo thời gian phản hồi nhanh nhất.

Ví dụ về hoạt động của DBMS:

Giả định: Bạn là một quản lý của một cửa hàng bán lẻ và bạn sử dụng một hệ thống quản lý cơ sở dữ liệu để lưu trữ thông tin về các sản phẩm, khách hàng và đơn đặt hàng.

1. Lưu trữ dữ liệu:

  • Cơ sở dữ liệu: Hệ thống DBMS của bạn chứa các bảng dữ liệu, bao gồm bảng sản phẩm, bảng khách hàng và bảng đơn đặt hàng.
  • Bảng sản phẩm: Lưu trữ thông tin về các sản phẩm như mã sản phẩm, tên sản phẩm, giá bán, số lượng tồn kho, v.v.
  • Bảng khách hàng: Lưu thông tin cá nhân của khách hàng như tên, địa chỉ, email, số điện thoại, v.v.
  • Bảng đơn đặt hàng: Lưu thông tin về các đơn đặt hàng bao gồm ngày đặt hàng, thông tin khách hàng, danh sách các sản phẩm được đặt hàng, v.v.

2. Truy xuất dữ liệu:

  • Người dùng: Bạn, nhân viên bán hàng, muốn xem thông tin chi tiết về một sản phẩm cụ thể.
  • Truy vấn SQL: Bạn sử dụng câu lệnh SQL để truy xuất dữ liệu từ bảng sản phẩm: SELECT * FROM Products WHERE ProductID = 'P001';
  • DBMS: Hệ thống DBMS phân tích và thực thi câu lệnh SQL này.
  • Kết quả: Hệ thống trả về thông tin chi tiết về sản phẩm có mã P001, bao gồm tên sản phẩm, giá bán, số lượng tồn kho, v.v.

3. Cập nhật dữ liệu:

  • Người dùng: Bạn muốn cập nhật số lượng tồn kho của sản phẩm P001 sau khi bán hàng.
  • Câu lệnh SQL: Bạn sử dụng câu lệnh để cập nhật dữ liệu: UPDATE Products SET StockQuantity = StockQuantity - 1 WHERE ProductID = 'P001';
  • DBMS: Hệ thống DBMS xác nhận và thực hiện cập nhật dữ liệu trong bảng sản phẩm.
  • Kết quả: Số lượng tồn kho của sản phẩm P001 giảm đi 1 đơn vị sau khi cập nhật thành công.

4. Bảo vệ dữ liệu:

  • Quản trị viên hệ thống: Đảm bảo rằng chỉ những người có quyền truy cập được phép truy xuất và cập nhật dữ liệu trong cơ sở dữ liệu.
  • DBMS: Hệ thống DBMS quản lý các quyền truy cập và đảm bảo tính bảo mật của dữ liệu bằng cách sử dụng các cơ chế xác thực và phân quyền.

5. Quản lý giao dịch:

  • Người dùng: Bạn nhận được nhiều đơn đặt hàng cùng một lúc và muốn đảm bảo rằng mỗi đơn đặt hàng được xử lý một cách đáng tin cậy.
  • DBMS: Hệ thống DBMS quản lý các giao dịch bằng cách thực hiện các thao tác đọc và ghi dữ liệu một cách nhất quán và đồng bộ.
  • Ghi nhật ký (Log): Hệ thống DBMS lưu trữ các hoạt động ghi nhật ký để đảm bảo có thể phục hồi dữ liệu trong trường hợp có lỗi xảy ra.

6. Sao lưu và phục hồi dữ liệu:

  • Quản trị viên hệ thống: Thực hiện sao lưu định kỳ của cơ sở dữ liệu để đảm bảo an toàn dữ liệu.
  • DBMS: Cung cấp các công cụ để sao lưu và phục hồi dữ liệu khi cần thiết, đảm bảo tính toàn vẹn của dữ liệu.

Phân loại hệ quản trị cơ sở dữ liệu

Hệ quản trị cơ sở dữ liệu có thể được phân loại dựa trên nhiều tiêu chí khác nhau, bao gồm cấu trúc dữ liệu, kiểu mối quan hệ, và mục đích sử dụng.

1. Theo cấu trúc dữ liệu

  • Hệ quản trị cơ sở dữ liệu quan hệ (Relational Database Management System – RDBMS): Lưu trữ dữ liệu trong các bảng có các mối quan hệ được xác định trước, dựa trên lý thuyết mối quan hệ. Ví dụ: MySQL, PostgreSQL, Oracle Database.
  • Hệ quản trị cơ sở dữ liệu phi quan hệ (Non-relational DBMS): Lưu trữ dữ liệu theo các cấu trúc dữ liệu phi quan hệ, chẳng hạn như các tài liệu, cặp khóa-giá trị, hoặc đồ thị. Ví dụ: MongoDB (tài liệu), Redis (cặp khóa-giá trị), Neo4j (đồ thị).

2. Theo mục đích sử dụng:

  • OLTP (Online Transaction Processing): Dùng để xử lý các giao dịch trực tuyến, đảm bảo hiệu suất cao và thời gian phản hồi nhanh. Ví dụ: Oracle Database, MySQL.
  • OLAP (Online Analytical Processing): Dùng để phân tích và truy vấn dữ liệu phức tạp, hỗ trợ các hoạt động phân tích kinh doanh và báo cáo. Ví dụ: Microsoft SQL Server, PostgreSQL.

3. Theo phương pháp lưu trữ:

  • Hệ quản trị cơ sở dữ liệu dạng dòng (Row-oriented DBMS): Lưu trữ dữ liệu dưới dạng dòng, thích hợp cho các ứng dụng thường xuyên truy cập vào toàn bộ dữ liệu của từng bản ghi. Ví dụ: PostgreSQL, Oracle Database.
  • Hệ quản trị cơ sở dữ liệu dạng cột (Column-oriented DBMS): Lưu trữ dữ liệu dưới dạng cột, phù hợp cho các ứng dụng cần truy vấn dữ liệu một cách phân tích và thống kê. Ví dụ: Apache Cassandra, Google Bigtable.

4. Theo tính năng đặc biệt:

  • Hệ quản trị cơ sở dữ liệu nhớ đệm (In-memory DBMS): Lưu trữ và xử lý dữ liệu trực tiếp trong bộ nhớ, giúp tăng tốc độ truy xuất dữ liệu. Ví dụ: Redis, Memcached.
  • Hệ quản trị cơ sở dữ liệu đám mây (Cloud DBMS): Cung cấp dịch vụ quản trị cơ sở dữ liệu trên nền tảng đám mây, giúp giảm chi phí vận hành và quản lý cơ sở dữ liệu. Ví dụ: Amazon RDS, Microsoft Azure SQL Database.

Top 10 hệ quản trị cơ sở dữ liệu phổ biến

#1. MySQL

MySQL - Hệ quản trị cơ sở dữ liệu phổ biến nhất hiện nay
MySQL – Hệ quản trị cơ sở dữ liệu phổ biến nhất hiện nay

Được phát hành lần đầu tiên vào năm 1995 và MySQL đang được phát triển bởi tập đoàn Oracle, có thể nói MySQL là một trong những hệ quản trị cơ sở dữ liệu được sử dụng phổ biến nhất hiện nay.

MySQL được viết bởi ngôn ngữ C/C++ nên có hiệu năng cao, dễ sử dụng, có tính khả chuyển và hỗ trợ nhiều nền tảng hệ điều hành (Windows, Linux, MacOS).

MySQL cũng tương thích với nhiều ngôn ngữ lập trình phổ biến như Java, Python, NodeJS…

MySQL được xây dựng theo kiến trúc Client-Server, bao gồm một máy chủ đa luồng hỗ trợ nhiều máy khách khác nhau.

Các bạn có thể đọc thêm tài liệu về MySQL tại đây: https://www.mysql.com/ hoặc https://www.mysqltutorial.org/

#2. MariaDB

Một trong các hệ quản trị cơ sở dữ liệu phổ biến hiện nay là MariaDB
Một trong các hệ quản trị cơ sở dữ liệu phổ biến hiện nay là MariaDB

MariaDB thực chất là một nhánh được tách ra từ quá trình phát triển MySQL với mục đích phi thương mại, có nghĩa là nó sẽ hoàn toàn miễn phí cho người sử dụng.

Cũng như MySQL thì MariaDB được viết bằng ngôn ngữ C/C++, Perl nhưng được tối ưu khá nhiều về mặt hiệu năng truy vấn dữ liệu.

Hiện tại thì MariaDB cũng hỗ trợ hầu hết các hệ điều hành phổ biến như Windows, Linux và MacOS… Nên anh em lập trình không phải lo về vấn đề môi trường để sử dụng MariaDB nha.

Do hoàn toàn miễn phí nên các bạn có thể tham khảo mã nguồn mở của MariaDB tại đây: https://github.com/MariaDB/server

Ngoài ra thì các bạn cũng có thể đọc thêm về các bài viết hướng dẫn của MariaDB tại đây nữa nhé: https://www.mariadbtutorial.com/

Xem thêm: Điểm khác biệt của MariaDB và MySQL

#3. Oracle

một số hệ quản trị cơ sở dữ liệu hiện nay

Là một hệ quản trị cơ sở dữ liệu đa mô hình do công ty phần mềm thứ 2 thế giới là Oracle xây dựng và phát triển.

Tất nhiên là chúng ta phải trả phí để có thể sử dụng được hệ quản trị CSDL này, thậm chí là chi phí khá đắt đối với các hệ thống lớn.

Oracle được viết bằng ngôn ngữ C/C++, Assembly nên cũng cho hiệu năng rất cao. Và tất nhiên thì Oracle cũng hỗ trợ hầu hết các nền tảng hệ điều hành hiện nay như Windows, Linux, MacOS

Oracle database thường được sử dụng để chạy các công việc liên quan đến xử lý giao dịch trực tuyến (OLTP), kho dữ liệu (DW) hoặc là hỗn hợp (OLTP và DW).

Các bạn có thể mua các gói dịch vụ tại các nhà cung cấp được Oracle ủy quyền.

Về tài liệu tham khảo thì các bạn có thể xem các hướng dẫn về Oracle tại đây: https://www.oracletutorial.com/

#4. MongoDB

mongoDB - Hệ quản trị cở dữ liệu phi quan hệ (NoSQL)
mongoDB – Hệ quản trị cở dữ liệu phi quan hệ (NoSQL)

Ở trên thì chúng ta đã đề cập đến 3 kiểu CƠ SỞ DỮ LIỆU CÓ QUAN HỆ, tiếp theo, chúng ta sẽ đến với MongoDB – đây là một hệ quản trị cở dữ liệu phi quan hệ (NoSQL)

Hiện tại thì MongoDB cũng là một hệ quản trị cơ sở dữ liệu mã nguồn mở, tức là nó miễn phí. Các bạn có thể tham khảo mã nguồn của MongoDB tại đây: https://github.com/mongodb/mongo

MongoDB được viết bằng nhiều ngôn ngữ lập trình khác nhau như C/C++, Go, JavaScript, Python và cũng hỗ trợ trên hầu hết các nền tảng hệ điều hành (Windows, Linux, MacOS..).

Đặc điểm của HỆ QUẢN TRỊ DỮ LIỆU PHI QUAN HỆ là dữ liệu được lưu lại dưới dạng JSON (JavaScript Object Notation) và gần như là các các bản ghi không nhất thiết phải giống nhau về cấu trúc.

Các bạn có thể đọc thêm tài liệu về MongoDB tại đây: https://www.mongodb.com/3

#5. PostgreSQL

các hệ qtcsdl phổ biến hiện nay là

Tiếp tục với một hệ quản trị cơ sở dữ liệu có quan hệ mã nguồn mở đó là PostgreSQL.

PostgreSQL được phát triển bởi khoa điện toán của trường đại học California tại Berkeley. PostgreSQL mở đầu nhiều khái niệm quan trọng cho các hệ quản trị cơ sở dữ liệu thương mại sau này mới có.

Được viết hoàn toàn bằng ngôn ngữ lập trình C nên tốc độ cũng như hiệu năng của PostgreSQL là rất tốt.

Đồng thời thì nó cũng hỗ trợ nhiều nền tảng như Windows, Linux, MacOS nên PostgreSQL đang ngày càng trở nên phổ biến hơn.

Với ưu điểm hỗ trợ nhiều truy vấn phức tạp thì PostgreSQL cũng đang là một ứng cử viên rất tiềm năng cho các hệ thống lớn sau này.

Các bạn có thể đọc thêm tài liệu về PostgreSQL tại đây: https://www.postgresqltutorial.com/

#6. Microsoft SQL Server

một số hệ quản trị cơ sở dữ liệu
Microsoft SQL Server DBMS

Là một hệ quản trị cơ sở dữ liệu quan hệ được xây dựng và phát triển bởi Microsoft, với phiên bản đầu tiên ra đời vào năm 1989 (SQL Server 1.0) đến nay đã là phiên bản SQL Server 2019, và cũng là phiên bản ổn định nhất.

Microsoft SQL Server được viết bằng ngôn ngữ C/C++ nên hiệu năng cũng như tốc độ truy vấn rất tốt.

Ban đầu thì Microsoft SQL Server chỉ hỗ trợ hệ điều hành Windows, nhưng sau này nó đã được phát triển để hỗ trợ trên hầu hết các nền tảng hệ điều hành Linux và MacOS.

Tuy không phải là một hệ quản trị dữ liệu mã nguồn mở, song Microsoft SQL được đánh giá khá cao là “tiền nào của nấy”.

Các bạn có thể download Microsoft SQL Server tại đây https://www.microsoft.com/en-us/sql-server/sql-server-downloads

#7. Redis

các hệ quản trị csdl

Redis (viết tắt của cụm từ REmote DIctionary Server) là một mã nguồn mở được sử dụng để lưu trữ dữ liệu có cấu trúc, có thể được sử dụng như một Database, bộ nhớ cache hoặc là một Message Broker.

Redis lưu trữ dữ liệu dưới dạng Key-Value, hỗ trợ việc sắp xếp, query, backup dữ liệu lên đĩa cứng để cho phép bạn có thể khôi phục hệ thống khi gặp sự cố.

Một vài kiểu dữ liệu trong Redis như String, List, Set, Hash…

Có thể nói Redis là một sự lựa chọn tuyệt vời khi cần đến một Server lưu trữ dữ liệu đòi hỏi tính mở rộng cao, chia sẻ nhiều tiến trình, nhiều ứng dụng và nhiều server khác nhau.

#8. Elasticsearch

một số hệ quản trị csdl hiện nay

Chính xác thì Elasticsearch là một công cụ tìm kiếm mã nguồn mở. Elasticsearch cung cấp bộ máy tìm kiếm dạng phân tán, có đầy đủ công cụ với giao diện web HTTP hỗ trợ dữ liệu kiểu JSON.

Elasticsearch được viết bằng ngôn ngữ lập trình Java và nó được ra đời vào năm 2016. Các bạn có thể tham khảo mã nguồn của Elasticsearch tại đây: https://github.com/elastic/elasticsearch

Hiện tại thì Elasticsearch hỗ trợ hầu hết các hệ điều hành Window, Linux, MacOS

Các bạn có thể download Elasticsearch tại đây nhé: https://www.elastic.co/downloads/

#9. Firebase

phần mềm hệ quản trị cơ sở dữ liệu
phần mềm hệ quản trị cơ sở dữ liệu Firebase

Được xây dựng và phát triển bởi Google, Firebase là một dịch vụ cơ sở dữ liệu dựa trên nền tảng công nghệ điện toán đám mây.

Sự ra đời của Firebase với mục đích hỗ trợ cho các lập trình giảm thiểu thao tác với cơ sở dữ liệu, từ đó tập trung vào việc phát triển ứng dụng hơn.

Với hệ thống server mạnh mẽ, sự tiện lợi cũng như việc bảo mật cực tốt đã giúp Firebase trở thành một trong những cái tên được nhiều nhà phát triển lựa chọn để xây dựng các hệ thống lớn.

Có thể kể đến một vài ưu điểm của Firebase như sau:

  • Chỉ việc tạo tài khoản và sử dụng.
  • Tốc độ phát triển nhanh.
  • Được hậu thuẫn bởi ông lớn Google.
  • Hỗ trợ các công nghệ mới (Machine Learning (học máy), AI)
  • Khả năng realtime (thời gian thực).
  • Tự động sao lưu vào khôi phục…

#10. SQLite

các hệ qtcsdl phổ biến hiện nay là?

SQLite là một hệ thống cơ sở dữ liệu quan hệ nhỏ, nó có đặc điểm là có thể tích hợp vào bên trong các trình ứng dụng khác.

SQLite được viết và phát triển bởi D. Richard Hipp sử dụng ngôn ngữ lập trình C, với mục đích không cần yêu cầu quản trị cơ sở dữ liệu mà vẫn có thể vận hành ứng dụng.

Chúng ta có thể liên kết SQLite tĩnh hoặc động tới ứng dụng, chỉ khoảng 400KB với cấu hình đầy đủ hoặc 259KB nếu bỏ qua một số tính năng tùy chọn thì SQLite thực sự rất nhẹ để tích hợp vào ứng dụng.

Các bạn có thể tham khảo các bài hướng dẫn về SQLite tại đây: https://www.sqlitetutorial.net/

Vậy là trong bài viết này mình đã cùng với các bạn điểm qua khái niệm Hệ quản trị CSDL và top 10 DBMS được sử dụng phổ biến nhất hiện nay rồi nhé.

Ngoài những hệ quản trị cơ sở dữ liệu mình đã liệt kê bên trên ra, nếu bạn còn biết thêm DBMS nào khác thì có thể comment ở phần bình luận để anh em cùng tìm hiểu nha.

Nguồn tham khảo: blogchiasekienthuc.com

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

Viết React Code sạch hơn như thế nào? (Phần 1)

clean react code
Viết React Code sạch hơn như thế nào? (Phần 1)

Tác giả: Reed Barger

Là một React developer, bất cứ ai đều muốn có thể viết ra những code sạch hơn, đơn giản và dễ đọc nhất có thể. Bài viết dưới đây sẽ cung cấp cho các React devs những cách hiệu quả nhất để clean code.

clean code react
Clean code React như thế nào?

1. Sử dụng JSX shorthands

Làm cách nào để bạn chuyển một giá trị true cho một giá trị đã cho? Trong ví dụ bên dưới đang sử dụng showTitle để hiển thị tiêu đề ứng dụng trong thành phần Navbar.

// src/App.js

export default function App() {
  return (
    <main>
      <Navbar showTitle={true} />
    </main>
  );
}

function Navbar({ showTitle }) {
  return (
    <div>
      {showTitle && <h1>My Special App</h1>}
    </div>
  )
}

Chúng ta có cần đặt thành showTitle Boolean một cách rõ ràng true không? Không! Một cách viết nhanh cần nhớ là bất kỳ phần mềm hỗ trợ nào được cung cấp trên một thành phần đều có giá trị mặc định là true.

Vì vậy, nếu thêm phần hỗ trợ showTitle trên Navbar, phần tử tiêu đề sẽ được hiển thị:

// src/App.js

export default function App() {
  return (
    <main>
      <Navbar showTitle />
    </main>
  );
}

function Navbar({ showTitle }) {
  return (
    <div>
      {showTitle && <h1>My Special App</h1>} // title shown!
    </div>
  )
}

Một cách viết tắt hữu ích khác cần ghi nhớ liên quan đến việc chuyển các chuỗi props. Khi truyền một giá trị prop là một chuỗi, bạn không cần phải đặt nó trong dấu ngoặc nhọn. Nếu đang đặt tiêu đề cho Navbar của mình, với title prop, chúng ta chỉ có thể đưa giá trị của nó vào dấu ngoặc kép:

// src/App.js

export default function App() {
  return (
    <main>
      <Navbar title="My Special App" />
    </main>
  );
}

function Navbar({ title }) {
  return (
    <div>
      <h1>{title}</h1>
    </div>
  )
}

2. Di chuyển những code không liên quan vào một file chung

Cách dễ nhất và quan trọng nhất để viết code React sạch hơn là làm tốt việc trừu tượng hóa code thành các thành phần React riêng biệt. Ứng dụng đang hiển thị một thành phần Navbar. Chúng ta đang lặp lại một loạt các bài đăng có .map() và hiển thị tiêu đề của chúng trên trang.

// src/App.js

export default function App() {
  const posts = [
    {
      id: 1,
      title: "How to Build YouTube with React"
    },
    {
      id: 2,
      title: "How to Write Your First React Hook"
    }
  ];

  return (
    <main>
      <Navbar title="My Special App" />
      <ul>
        {posts.map(post => (
          <li key={post.id}>
            {post.title}
          </li>
        ))}
      </ul>
    </main>
  );
}

function Navbar({ title }) {
  return (
    <div>
      <h1>{title}</h1>
    </div>
  );
}

Làm thế nào để có thể viết những code này sạch hơn? Tại sao không tóm tắt những đoạn code đang lặp lại – các bài đăng – và hiển thị chúng trong một thành phần riêng biệt, được gọi là FeaturedPosts.

// src/App.js

export default function App() {
 return (
    <main>
      <Navbar title="My Special App" />
      <FeaturedPosts />
    </main>
  );
}

function Navbar({ title }) {
  return (
    <div>
      <h1>{title}</h1>
    </div>
  );
}

function FeaturedPosts() {
  const posts = [
    {
      id: 1,
      title: "How to Build YouTube with React"
    },
    {
      id: 2,
      title: "How to Write Your First React Hook"
    }
  ];

  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}

3. Tạo các file riêng biệt cho từng thành phần

Tương tự như cách trừu tượng hóa code thành các phần riêng biệt để làm cho ứng dụng dễ đọc hơn, để làm cho các file ứng dụng dễ đọc hơn, chúng ta có thể đặt từng thành phần vào mỗi file riêng biệt. Điều này có nghĩa là mỗi file chỉ chịu trách nhiệm cho một thành phần và không có sự nhầm lẫn thành phần đến từ đâu nếu chúng ta muốn sử dụng lại nó trên ứng dụng của mình.

// src/App.js
import Navbar from './components/Navbar.js';
import FeaturedPosts from './components/FeaturedPosts.js';

export default function App() {
  return (
    <main>
      <Navbar title="My Special App" />
      <FeaturedPosts />
    </main>
  );
}
// src/components/Navbar.js

export default function Navbar({ title }) {
  return (
    <div>
      <h1>{title}</h1>
    </div>
  );
}
// src/components/FeaturedPosts.js

export default function FeaturedPosts() {
  const posts = [
    {
      id: 1,
      title: "How to Build YouTube with React"
    },
    {
      id: 2,
      title: "How to Write Your First React Hook"
    }
  ];

  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}

Ngoài ra, bằng cách chia nhỏ thành từng file riêng biệt như thế này sẽ tránh việc khiến một file trở nên quá cồng kềnh.

  3 bước tối ưu hiệu năng React App bằng các API mới của React
  5 sai lầm thường thấy khi viết react component

4. Chuyển chức năng được chia sẻ vào React hooks

Xem xét các component FeaturedPosts, thay vì hiển thị dữ liệu bài đăng tĩnh, nếu bạn muốn tìm nạp dữ liệu bài đăng của mình từ một API. Bạn có thể xem kết quả bên dưới cho điều đó

// src/components/FeaturedPosts.js

import React from 'react';

export default function FeaturedPosts() {
  const [posts, setPosts] = React.useState([]);  	
    
  React.useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/posts')
      .then(res => res.json())
      .then(data => setPosts(data));
  }, []);

  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}

Tuy nhiên, điều gì sẽ xảy ra nếu thực hiện yêu cầu này đối với dữ liệu trên nhiều thành phần?

Giả sử ngoài một FeaturedPosts component, bạn muốn tạo một thành phần chỉ có tên là Posts với dữ liệu cũng giống như vậy. Chúng tôi sẽ phải sao chép logic đã sử dụng để tìm nạp dữ liệu của mình và paste vào trong thành phần đó.

Để tránh phải làm điều đó, tại sao chúng ta không sử dụng một React hook mới mà chúng ta có thể gọi useFetchPosts

// src/hooks/useFetchPosts.js

import React from 'react';

export default function useFetchPosts() {
  const [posts, setPosts] = React.useState([]);  	
    
  React.useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/posts')
      .then(res => res.json())
      .then(data => setPosts(data));
  }, []);

  return posts;
}

Khi đã tạo hook này trong một file ‘hooks’ chuyên biệt, bạn có thể sử dụng lại nó trong bất kỳ thành phần nào

// src/components/FeaturedPosts.js

import useFetchPosts from '../hooks/useFetchPosts.js';

export default function FeaturedPosts() {
  const posts = useFetchPosts()

  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}

Bài viết được phỏng dịch theo bài viết gốc tại freecodecamp.org

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

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

Cấu trúc dữ liệu từ điển Dictionary trong Python

Cấu trúc dữ liệu từ điển Dictionary trong Python

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

Trong Python có tới 4 kiểu cấu trúc dữ liệu là List, Tuple, Set và Dictionary. Trong các bài trước chúng ta đã lần lượt làm quen với các kiểu dữ liệu này và còn lại Dictionary, một cấu trúc rất hay dùng trong Python. Trong bài viết này, cùng TopDev tìm hiểu về cấu trúc dữ liệu từ điển Dictionary trong Python.

Từ điển – Dictionary trong Python

Từ điển dữ liệu (Dictionary) còn được gọi là mảng liên kết (associative array) trong một số ngôn ngữ lập trình, là một dạng danh sách như bạn đã được tìm hiểu. Có một điểm khác là các phần tử trong danh sách được truy xuất thông qua vị trí thì phần tử trong từ điển được truy xuất qua khóa (key). Bạn có thể định nghĩa khóa này, nó có thể là một chuỗi hoặc số nhưng nó phải là duy nhất trong từ điển.

Tại sao vậy? Chúng ta liên tưởng đến nhưng tình huống thực tế như, hai người có cùng một số điện thoại, vậy khi gọi đến biết ai là người nghe máy. Hai người có cùng một số tài khoản, vậy biết chuyển khoản cho ai bây giờ? Chính vì vậy, khóa (key) trong từ điển phải là duy nhất.

Vậy kiểu dữ liệu Dict trong Python là gì?

Kiểu dữ liệu Dict (viết tắt của Dictionary) trong Python là một kiểu dữ liệu lưu trữ các cặp key-value, tương tự như List và Tuple. Tuy nhiên, các giá trị trong Dict không được sắp xếp theo một trật tự cụ thể nào.

Từ điển trong Python cũng có thể tưởng tượng giống như một cuốn từ điển Anh – Việt chẳng hạn. Bạn muốn tra từ “python” – tương ứng với khóa trong Dictionary, bạn sẽ có được phần diễn giải chính là giá trị trong Dictionary. Vậy từ điển bao gồm rất nhiều các phần tử mà mỗi phần tử đi theo cặp khóa – giá trị (key-value).

  Biến và kiểu dữ liệu cơ bản trong Python

Cách sử dụng Dictionary trong Python

Khai báo Dictionary

Dictionary trong Python được khai báo với cặp dấu ngoặc nhọn {} bao ngoài giống như với Set. Bên trong các phần tử theo cặp (khóa và giá trị) được phân tách bởi dấu phẩy, phân tách giữa khóa và giá trị của từng phần tử bởi dấu hai chấm. Cú pháp chung như sau:

dictionary_name = {key_1: value_1, key_2: value_2, ..., key_n: value_n}

Ví dụ:

friend_ages = {"Rolf": 24, "Adam": 30, "Anne": 27}
print(friend_ages["Adam"]) # Kết quả là 30

Chúng ta cũng có thể sử dụng hàm có sẵn dict() để khai báo một Dictionary.

friend_ages = dict({"Rolf": 24, "Adam": 30, "Anne": 27})
# Hoặc
friend_ages = dict([("Rolf", 24), ("Adam", 30), ("Anne", 27)])

Chú ý:

  • Khóa của Dictionary có thể là chuỗi hoặc số, khóa này là duy nhất ở từng cấp.
  • Giá trị của Dictionary có thể chuỗi, số hoặc các cấu trúc List, Tuple, Set hoặc thậm chí là Dictionary.

Một ví dụ khai báo Dictionary với giá trị phức tạp:

friends = {
  "Rolf": {
    "phone": "09382993433",
    "address": "Boston, America",
    "age": 30
  },
  "Bob": {
    "phone": "03099483832",
    "address": "London, England",
    "age": 33
  },
  "Anne": {
    "phone": "00393982224",
    "address": "Texas, America",
    "age": 25
  }
}

Truy xuất giá trị

Dictionary có thể truy xuất giá trị từng phần tử thông qua các khóa theo cú pháp:

dictionary_name[key_x]

Ví dụ, trong từ điển friends ở trên, chúng ta có thể truy xuất thông tin (giá trị) của Bob (khóa) như sau:

print(friends["Bob"]) # Kết quả là {'phone': '03099483832', 'address': 'London, England', 'age': 33}

Chú ý, mỗi phần tử trong Dictionary friends này lại là một Dictionary nên chúng ta có thể truy xuất tiếp đến tuổi tuổi của Bob như sau:

print(friends["Bob"]["age"]) # Kết quả là 33

Khi truy xuất đến các phần tử trong Dictionary, nếu khóa không tồn tại, chương trình sẽ báo lỗi KeyError.

print(friends["FirebirD"]) # Kết quả lỗi KeyError: "FirebirD"

Do vậy trước khi truy xuất giá trị một phần tử trong từ điển, chúng ta cần kiểm tra xem khóa có tồn tại hay không với toán tử in.

print("FirebirD" in friends) # Kết quả là False, FirebirD không có trong danh sách friends.

>>> Xem thêm: Kiểu dữ liệu chuỗi và định dạng chuỗi trong Python

Thay đổi giá trị

Dictionary trong Python có thể thay đổi thêm bớt các phần tử, thay đổi giá trị của các phần tử hiện có.

Thêm và cập nhật phần tử

Dictionary truy xuất thông qua khóa, do vậy khi gán giá trị cho một phần tử:

  • Khóa tồn tại thì giá trị phần tử được cập nhật.
  • Khóa không tồn tại thì Dictionary được thêm một phần tử có khóa và giá trị trong câu lệnh.
friend_ages = {"Rolf": 24, "Adam": 30, "Anne": 27}

# Thay đổi giá trị
friend_ages["Adam"] = 31

# Thêm một phần tử
friend_ages["Firebird"] = 37

print(friends) # Kết quả là {'Rolf': 24, 'Adam': 31, 'Anne': 27, 'Firebird': 37}

Ngoài ra chúng ta có thể sử dụng phương thức .update() để thêm hoặc chỉnh sửa giá trị nhiều phần tử vào từ điển. Trong ví dụ tiếp theo, chúng ta vừa thực hiện sửa tuổi của Rolf thành 25 và thêm một phần tử mới vào từ điển.

friend_ages = {"Rolf": 24, "Adam": 30, "Anne": 27}
new_friend_ages = {"Rolf": 25, "FirebirD": 37}
friend_ages.update(new_friend_ages)
print(friend_ages) # Kết quả là {'Rolf': 25, 'Adam': 30, 'Anne': 27, 'FirebirD': 37}

Xóa phần tử khỏi từ điển

Cũng giống như List, Dictionary có rất nhiều các phương thức có sẵn để có thể xóa một phần tử khỏi từ điển như .clear(), .pop(), .popitem() hoặc sử dụng từ khóa del.

.clear() Xóa toàn bộ các phần tử khỏi từ điển.

friend_ages = {"Rolf": 24, "Adam": 30, "Anne": 27}
friend_ages.clear()
print(friend_ages) # Kết quả là {}

.popitem() Xóa một phần tử ngẫu nhiên

.pop() Xóa một phần tử với khóa cho trước khỏi từ điển.

friend_ages = {"Rolf": 24, "Adam": 30, "Anne": 27}
friend_ages.pop("Adam")
print(friend_ages) # Kết quả là {'Rolf': 24, 'Anne': 27}

del Xóa một phần tử hoặc xóa hẳn biến chứa Dictionary.

friend_ages = {"Rolf": 24, "Adam": 30, "Anne": 27}
del friend_ages["Adam"]
print(friend_ages) # Kết quả là {'Rolf': 24, 'Anne': 27}

del friend_ages
print(friend_ages) # Kết quả lỗi NameError: name 'friend_ages' is not defined

Một số phương thức trong Dictionary

Phương thức .copy()

Phương thức này trả về một bản copy riêng biệt. Chú ý, phương thức .copy() có điểm khác so với gán biến trong Python. Chúng ta cùng xem ví dụ sau:

friend_ages = {"Rolf": 24, "Adam": 30, "Anne": 27}
copy_friend_ages = friend_ages.copy()
new_friend_ages = friend_ages

friend_ages.clear()

print(copy_friend_ages) # Kết quả là {'Rolf': 24, 'Adam': 30, 'Anne': 27}
print(new_friend_ages) # Kết quả là {}

Như vậy, với phương thức .copy() toàn bộ bộ nhớ liên quan đến biến friend_ages được copy sang một vùng khác trong bộ nhớ, do vậy biến cũ thay đổi thì biến mới không thay đổi do tham chiếu đến vùng nhớ khác trên bộ nhớ. Còn khi gán giá trị bằng dấu =, biến đó vẫn tham chiếu đến vùng nhớ của biến cũ, nên khi biến cũ thay đổi, biến mới cũng thay đổi theo.

Phương thức .get()

Trả về giá trị một phần tử trong Dictionary với một khóa cho trước, nó giống với truy xuất giá trị tại mục 1.2 nhưng có một khác biệt nhỏ, nếu khóa không tồn tại, chương trình sẽ không báo lỗi mà trả về giá trị None.

friend_ages = {"Rolf": 24, "Adam": 30, "Anne": 27}

print(friend_ages.get("FirebirD")) # Kết quả là None
print(friend_ages.get("Rolf")) # Kết quả là 24
print(friend_ages["FirebirD"]) # Kết quả lỗi KeyError: 'FirebirD'

Phương thức .keys() và .values()

Hai phương thức này trả về danh sách khóa và danh sách các giá trị của từ điển. Ví dụ:

friend_ages = {"Rolf": 24, "Adam": 30, "Anne": 27}

print(friend_ages.keys())
# Kết quả dict_keys(['Rolf', 'Adam', 'Anne'])

print(friend_ages.values())
# Kết quả dict_values([24, 30, 27])

So sánh List, Tuple, Set và Dictionary

Bạn đã được giới thiệu 4 cấu trúc dữ liệu có trong Python là List, Tuple, Set và Dictionary, có vẻ như hơi nhiều thứ rắm rối. Trong từng bài viết, chúng ta đã có những so sánh hai khái niệm một với nhau, giờ là lúc chúng ta tổng kết lại toàn bộ những gì đã học về 4 cấu trúc dữ liệu này:

Cách khai báo:

  • [value_1, value_2, …, value_n]: Khai báo danh sách (List)
  • (value_1, value_2, …, value_n): Khai báo Tuple
  • {value_1, value_2, …, value_n}: Khai báo tập hợp (Set)
  • {key_1:value_1, key_2:value_2, …, key_n:value_n}: Khai báo từ điển (Dictionary)

Sau khi làm quen với 4 cấu trúc List, Tuple, Set và Dictionary, có lẽ bạn sẽ rất băn khoăn: Nên lựa chọn cấu trúc nào cho phù hợp với chương trình của bạn? Trước khi đến với câu trả lời, tôi khuyên bạn hãy đọc thật kỹ lại kiến thức từng cấu trúc này:

Sau đó, chúng ta cùng đúc kết để có được câu trả lời cho: Khi nào dùng List, Tuple, Set hay Dictionary trong Python?

  • Sử dụng List khi muốn có dữ liệu truy xuất theo thứ tự (vị trí của phần tử tăng dần từ 0), dữ liệu List ở dạng đơn giản và thay đổi thường xuyên.
  • Sử dụng Set khi muốn dữ liệu là duy nhất và dễ dàng thực hiện các phép toán tập hợp như phép giao, hợp, trừ.
  • Sử dụng Tuple khi dữ liệu không thay đổi và cần tốc độ xử lý.
  • Sử dụng Dictionary khi dữ liệu thay đổi liên tục, có sự liên kết logic giữa khóa và giá trị và một điểm nhấn quan trọng là muốn truy xuất dữ liệu nhanh thông qua khóa.

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

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

Đừng sudo, nếu không biết virtualenv

Đừng sudo, nếu không biết virtualenv

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

  • “Mình không cài bằng pip được…”
  • “chạy sudo pip … nhé “

Đó là những câu hỏi và trả lời thường xuất hiện, khi người ta nói về pip. Đây là vấn đề chung với những người dùng không hiểu về phân quyền trên UNIX và thường sẽ làm mọi thứ trở nên rắc rối thêm bằng cách chạy sudo.

  Hướng dẫn cài đặt VirtualBox trên Ubuntu chi tiết nhất
  JavaScript Runtime Environment là gì?

sudo – câu lệnh thần thánh

Sudo XKCD

Một mẩu truyện nhỏ cho thấy sức mạnh của sudo, khi ta nói mà đối phương không nghe, thêm sudo vào đầu là mọi thứ đều sẽ hoạt động.

sudo – SUperuser DO

Trên các hệ điều hành *NIX có chia ra nhiều user để nhiều người dùng chung một máy tính. Trong đó, mọi máy tính luôn có user root – user có quyền năng tối thượng, thường được gọi là quyền admin hay superuser, có thể thực hiện bất kỳ thay đổi gì trên máy tính. Do có quyền năng vô hạn như vậy, nên khi thực hiện việc gì cũng ẩn chứa nguy hiểm, một câu lệnh gõ nhầm cũng có thể phá huỷ hệ thống, và nếu như ai cũng là root thì hệ thống sẽ loạn, người dùng không hiểu biết có thể cài đặt các loại virus/malware lên máy tính (hi Windows).

Để giải quyết vấn đền này, người ta sản xuất ra phần mềm tên “sudo”, cho phép cấp quyền cho các user nhất định. Với sự tồn tại của sudo, người ta thay đổi cách dùng máy tính:

  • tất cả mọi người đều có tài khoản riêng của mình
  • cấp quyền root cho một số user cụ thể
  • user được cấp quyền có thể chạy câu lệnh như user root.

Khi nào cần quyền root

Mỗi user trên *NIX được cấp một thư mục gọi là thư mục HOME. Có thể truy cập thư mục này bằng:

cd ~

hay

cd $HOME

Thư mục này thường có đường dẫn /home/yourname/. và mặc định thuộc toàn quyền sử dụng của user , thích tạo/sửa/xoá file nào thì tuỳ ý.

Hệ thống có thư mục đặc biệt /tmp, ai cũng đều có thể ghi vào (nhưng người này không thể can thiệp vào file/thư mục của người kia) – và các file trong này sẽ tự bị xoá mỗi khi máy tắt.

Còn lại, các thư mục khác trên máy tính chỉ có root mới có thể thay đổi (/etc, /log, /var, /usr, /bin …), khi sử dụng các phần mềm thực hiện thay đổi ảnh hưởng đến cả hệ thống, ví dụ dùng apt-get để cài package, lý do ta cần chạy sudo vì:

  • apt-get sẽ ghi file vào các thư mục nói trên. Ví dụ khi cài package nginx, các file sau sẽ được tạo ra:
$ dpkg -L nginx | grep nginx
/var/cache/nginx
/var/log/nginx
/usr/lib/nginx
/usr/lib/nginx/modules
/usr/share/doc/nginx
/usr/share/doc/nginx/CHANGES.ru.gz
/usr/share/doc/nginx/changelog.Debian.gz
/usr/share/doc/nginx/changelog.gz
/usr/share/doc/nginx/copyright
/usr/share/doc/nginx/README
/usr/share/man/man8/nginx.8.gz
/usr/share/lintian/overrides/nginx
/usr/share/nginx
/usr/share/nginx/html
/usr/share/nginx/html/index.html
/usr/share/nginx/html/50x.html
/usr/sbin/nginx-debug
/usr/sbin/nginx
/etc/init.d/nginx-debug
/etc/init.d/nginx
/etc/logrotate.d/nginx
/etc/nginx
/etc/nginx/koi-win
/etc/nginx/fastcgi_params
/etc/nginx/uwsgi_params
/etc/nginx/mime.types
/etc/nginx/koi-utf
/etc/nginx/nginx.conf
/etc/nginx/conf.d
/etc/nginx/conf.d/default.conf
/etc/nginx/scgi_params
/etc/nginx/win-utf
/etc/default/nginx-debug
/etc/default/nginx
/etc/nginx/modules
...

Chỉ user root mới có quyền ghi vào /etc/ /bin … đó là lý do cần thêm sudo khi người dùng với user của họ chạy câu lệnh apt-get.

Nếu ta cấu hình cho apt-get không ghi vào các thư mục trên, ta hoàn toàn có thể chạy apt-get để cài đặt package trên thư mục home của mình. Các chương trình được cài xong sẽ chỉ mình mình dùng được, do user khác không truy cập được vào các file này.

sudo pip

Khi dùng pip cài ipython (không dùng virtualenv), đây là nơi ipython sẽ được cài:

root@hvn:~# pip show ipython
Name: ipython
Version: 6.1.0
Summary: IPython: Productive Interactive Computing
Home-page: https://ipython.org
Author: The IPython Development Team
Author-email: ipython-dev@python.org
License: BSD
Location: /usr/local/lib/python3.5/dist-packages
Requires: prompt-toolkit, setuptools, pygments, simplegeneric, jedi, pexpect, traitlets, pickleshare, decorator

/usr/local là thư mục chỉ root mới được quyền ghi, vì vậy bạn không thể chạy pip install PACKAGE, bởi user thông thường không có quyền (permission denied) ghi vào /usr

$ pip install phg
..,
PermissionError: [Errno 13] Permission denied: '/usr/local/lib/python3.5/dist-packages/phg-1.1.0.dist-info'

Mô-tuýp truyền thống lại xảy ra:

  • “Mình không cài được …”
  • “sudo pip …”

Cách làm này không sai, nhưng thiếu hiểu biết:

  • nó cài đặt package lên thư mục hệ thống /usr/local/lib, khi có nhu cầu sử dụng 2 phiên bản của cùng 1 phần mềm, ta không thể gỡ một bản đi và giữ lại bản kia (VD: django 1.7 và django 1.11)
  • không phải code nào cài từ pip cũng an toàn, khi chạy với user root cài một package chứa code phá hoại, nó có thể huỷ diệt cả hệ thống (vì user root có quyền làm mọi thứ).

Giải pháp là virtualenv!

Virtualenv

virtualenv là một phần mềm viết bằng Python, giúp tạo ra các “môi trường ảo” để tách biệt các môi trường của các project khác nhau.

Mỗi “môi trường ảo” về bản chất chỉ là một thư mục, với một vài thay đổi khiến cho khi ta dùng pip để cài package, các package sẽ được cài vào thư mục này. Điều này giải quyết các vấn đề nói trên:

  • tách biệt các môi trường giữa các project, 2 project có thể dùng 2 phiên bản khác nhau của cùng 1 phần mềm.
  • người dùng có thể tạo môi trường ảo trong thư mục $HOME của mình, không cần chạy sudo – không ảnh hưởng đến hệ thống.

virtualenv hoạt động được là nhờ vào cách mà Python thực hiện import. Luật import của Python, khi ta import spam:

  • Tìm các builtin module xem có cái nào tên là spam không. Danh sách các builtin module được chứa trong sys:
 python -c 'import sys; print(sys.builtin_module_names)'
('__builtin__', '__main__', '_ast', '_bisect', '_codecs', '_collections', '_functools', '_heapq', '_io', '_locale', '_md5', '_random', '_sha', '_sha256', '_sha512', '_socket', '_sre', '_struct', '_symtable', '_warnings', '_weakref', 'array', 'binascii', 'cPickle', 'cStringIO', 'cmath', 'datetime', 'errno', 'exceptions', 'fcntl', 'gc', 'grp', 'imp', 'itertools', 'marshal', 'math', 'operator', 'posix', 'pwd', 'select', 'signal', 'spwd', 'strop', 'sys', 'syslog', 'thread', 'time', 'unicodedata', 'xxsubtype', 'zipimport', 'zlib')
  • Nếu không thấy, tìm lần lượt trong các thư mục chứa trong list : sys.path, cho đến khi tìm thấy file spam.py.
  • Nếu vẫn không thấy, raise Exception ImportError.

Khi ta bật (activate) một virtualenv lên (source), thực tế ta thay đổi sys.path, nhét đường dẫn đến “môi trường ảo” hiện tại lên đầu sys.path, vì vậy khi thực hiện import, Python sẽ tìm trong “môi trường ảo” trước.

Đọc kỹ những dòng sau để thấy sự ảnh hưởng của virtualenv với Python sys.path, khi bật virtualenv, đường dẫn tới virtualenv sẽ xuất hiện trong sys.path, tức module / code nào nằm trong thư mục /home/hvn/myvenv/lib/python3.6/site-packages đều có thể được import.

$ python3 -m venv myvenv
$ source myvenv/bin/activate
(myvenv) $ python3 -c 'import sys; print(sys.path)'
['', '/usr/lib/python36.zip', '/usr/lib/python3.6', '/usr/lib/python3.6/lib-dynload', '/home/hvn/myvenv/lib/python3.6/site-packages']
(myvenv) $ deactivate
$ python3 -c 'import sys; print(sys.path)'
['', '/usr/lib/python36.zip', '/usr/lib/python3.6', '/usr/lib/python3.6/lib-dynload', '/usr/local/lib/python3.6/dist-packages', '/usr/lib/python3/dist-packages']

Với virtualenv, ta sẽ không bao giờ phải sudo pip nữa, mỗi project sẽ có một môi trường riêng biệt, không ai ảnh hưởng tới ai. Và chỉ gõ sudo pip khi cần thay đổi 1 package trên toàn hệ thống.

Sử dụng pip trong venv

Cho python3.6 trở lên, ví dụ trên Ubuntu 18.04, xem tài liệu cho lệnh dùng trên Windows.

$ python3 -m venv myvenv
$ source myvenv/bin/activate
(myvenv) $ python3 -m pip install django
Collecting django
  Cache entry deserialization failed, entry ignored
  Downloading https://files.pythonhosted.org/packages/5c/63/6d7efecbf3f06db8c6577950a24a191e55cadf7cda4d7fe6976206c886dd/Django-3.0.7-py3-none-any.whl (7.5MB)
    100% |████████████████████████████████| 7.5MB 206kB/s
Collecting pytz (from django)
  Using cached https://files.pythonhosted.org/packages/4f/a4/879454d49688e2fad93e59d7d4efda580b783c745fd2ec2a3adf87b0808d/pytz-2020.1-py2.py3-none-any.whl
Collecting sqlparse>=0.2.2 (from django)
  Using cached https://files.pythonhosted.org/packages/85/ee/6e821932f413a5c4b76be9c5936e313e4fc626b33f16e027866e1d60f588/sqlparse-0.3.1-py2.py3-none-any.whl
Collecting asgiref~=3.2 (from django)
  Cache entry deserialization failed, entry ignored
  Downloading https://files.pythonhosted.org/packages/68/00/25013f7310a56d17e1ab6fd885d5c1f216b7123b550d295c93f8e29d372a/asgiref-3.2.7-py2.py3-none-any.whl
Installing collected packages: pytz, sqlparse, asgiref, django
Successfully installed asgiref-3.2.7 django-3.0.7 pytz-2020.1 sqlparse-0.3.1
(myvenv) $ python
Python 3.6.9 (default, Apr 18 2020, 01:56:04)
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import django
>>> django.__version__
'3.0.7'
>>> quit()

$ python3 -m pip freeze
asgiref==3.2.7
Django==3.0.7
pkg-resources==0.0.0
pyfml==0.0.0
pytz==2020.1
sqlparse==0.3.1

Kết luận

sudo là sức mạnh, đừng chỉ vì quá mạnh mà thích làm gì cũng được 🙄

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

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

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

Sửa lỗi jenkins No Java executable found in current PATH

Sửa lỗi jenkins No Java executable found in current PATH

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

Sửa lỗi jenkins No Java executable found in current PATH

Đây là lỗi khi bạn start service jenkins. Nguyên nhân là do jenkins không tìm thấy Java Path.

  Cài Plugin cho Jenkins, Cài Maven Plugin cho Jenkins
  Hướng dẫn cấu hình JDK (Java) cho Jenkins

Sửa lỗi jenkins "No Java executable found in current PATH".

Có 2 nguyên nhân:

  • Trường hợp 1: Do bạn chưa cài Java trên máy tính or chưa cấu hình environment cho Java
  • Trường hợp 2: Đã cài Java và cấu hình environment nhưng jenkins không nhận Java PATH (thường là bị trên ubuntu do bạn cài JDK từ oracle bằng tay)

Sửa lỗi jenkins No Java executable found in current PATH.

Trường hợp 1:

Bạn cài đặt Java và cấu hình environment bằng lệnh:

sudo apt install openjdk-8-jre

Hoặc tải file tar.gz rồi cài đặt bằng tay như tại đây.

Trường hợp 2:

Mở file cấu hình jenkins bằng lệnh sau:

sudo vi /etc/init.d/jenkins

Sửa dòng thêm folder bin trong thư mục java của bạn vào sau biến PATH, nếu bạn cài open jdk thì nó sẽ có dạng /usr/lib/jvm/java-8-openjdk-amd64/bin/, còn trên máy mình cài java ở folder /opt/java/jdk1.8.0_261/bin nên mình sẽ sửa thành như sau:

PATH=/bin:/usr/bin:/sbin:/usr/sbin:/opt/java/jdk1.8.0_261/bin

Khởi động lại jenkins:

sudo service jenkins start
sudo service jenkins status

Sửa lỗi jenkins No Java executable found in current PATH

Reference: https://stackoverflow.com/questions/39621263/jenkins-fails-when-running-service-start-jenkins

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

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

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

Deadlock in Java – something you should know 1

Deadlock in Java

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

Nếu bạn đã có kinh nghiệm hoặc đã tiếp xúc qua với Java Concurrency, hẳn không còn xa lạ gì với khái niệm DeadLock. Tuy nhiên, bài viết này vẫn cung cấp một cái nhìn tổng quan, dễ hiểu hơn về DeadLock.

Dành cho những ai đang muốn tìm hiểu về deadlock. Bắt đầu ngay thôi nào!

  Sử dụng Dead Letter Exchange trong RabbitMQ
  Giới thiệu Temporal Dead Zone trong Javascript

1. DeadLock là gì?

Deadlock is a situation where a set of processes are blocked because each process is holding a resource and waiting for another resource acquired by some other process.

Deadlock là tình trạng các process block lẫn nhau do process này thì chờ tài nguyên kia, tài nguyên kia thì đang được một process khác nữa giữ lấy

Dead – Chết, nghe thôi đã thấy lạnh. Lock – Khóa, khóa lại trong nhau mà chết là từ chính xác dùng để diễn tả về Dead Lock

Deadlock lock and waitVòng lặp không lối thoát – Nguồn ảnh / Source: geeksforgeeks.org

Xem tin tuyển dụng Java mới nhất trên TopDev

2. Xảy ra lúc nào?

Tuy vậy, có phải lúc nào cũng xảy ra deadlock hay không?. Câu trả lời là không. Ở một số trường hợp liệt kê dưới đây sẽ xảy ra:

  • Mutual exclusion – Loại trừ nhau
  • Lock & wait – Chờ rồi tèo
  • No preemption – Không ưu tiên
  • Circular wait – Chờ nhau theo vòng tròn

2.1 Mutual Exclusion

Loại trừ lẫn nhau chính xác là khi hai hay nhiều thread cần sử dụng chung một resource. Nhiều connection đòi thực thi trên một table là ví dụ điển hình.

Một connection đều yêu cầu được ghi record mới vào table, nhưng table thì đang được lock bởi thread khác. Deadlock coming

2.2 Lock and wait

Khóa và chờ cũng gần giống như loại trừ lẫn nhau. Trường hợp này là một thread cứ chày cối dữ lấy tài nguyên (resource) không buông. Các thread khác thì cứ chờ.

Chờ hoài không thấy, chờ người nơi ấy. Dẫn tới chờ rồi chết cả đám

2.3 No preemption

Không có quyền ưu tiên. Trường hợp này được hiểu là resource A đang rất cần resource, nhưng nó không có quyền lấy resource từ thằng B đang giữ nó. Hai thằng giành nhau cũng xảy ra DeadLock

2.4 Circular Wait

Circular Wait là chờ vòng tròn, lặp trong vô vọng. Thằng T1 thì cần tài nguyên R2, T2 thì cần tài nguyên R3, T3 thì cần tài nguyên R1 của T1.

Nhức cả cái đầu nhưng xoay mòng mòng thành một cái vòng chờ nhau không lối thoát

Circular Wait, đợi nhau trong vòng tròn vô tận. Nguồn ảnh/ Source: The Robert C. Martin Clean Code Collection

3. Tổng kết

Deadlock là nỗi sợ to lớn với dân lập trình multi thread, concurency. Mỗi khi nó coming, y như cái tên của nó, chỉ có chết. Nhưng biết thì sẽ luôn có cách để phòng tránh.

Ở phần hai của series bài viết về deadlock sẽ là cách phòng tránh đối với từng loại. Đón đọc nha!.

4. Tham khảo

Wish you have best of luck. Have a good day!. Happy coding!

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

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

Xem thêm Tuyển lập trình Java hấp dẫn trên TopDev

5 tips giúp lập trình viên TẬP TRUNG hơn khi NGỒI CODE

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

Chào anh em, thực ra dù anh em làm gì, trong lĩnh vực nào đi chăng nữa thì việc “tập trung” gần như là một trong những điều kiện tiên quyết để anh em nâng cao hiệu suất làm việc.

  "Code dễ đọc" là như thế nào?
  3 tips làm việc với JavaScript giúp bạn tiết kiệm thời gian

Với anh em làm lập trình thì sự tập trung lại càng cần thiết hơn nữa, vì bản chất của công việc này sẽ đòi hỏi phải sử dụng trí não rất nhiều.

5 tips giúp lập trình viên TẬP TRUNG hơn khi NGỒI CODE

Vậy một câu hỏi đặt ra là làm thế nào để tập trung ngồi code được đây? Vâng, và trong bài viết này mình sẽ chia sẻ với anh em làm lập trình một vài tips mà mình đã áp dụng và mình thấy nó khá là hữu ích và hiệu quả đối với cá nhân mình.

Anh em có thể tham khảo, nếu thấy phù hợp thì có thể áp dụng cho mình đã nâng cao năng suất làm việc lên nhé. Điều này không những tốt cho cả công việc của công ty, mà còn tốt cho cả anh em nữa

#1. Dừng việc nghe nhạc trên Youtube

Nhiều anh em làm lập trình khi ngồi code thường có thói quen nghe nhạc và mình cũng là một trong số đó.

Việc nghe nhạc nào thì tùy vào sở thích của mỗi người, nhưng mình tin chắc rất nhiều anh em thường nghe nhạc trên Youtube là chủ yếu.

5 tips giúp lập trình viên TẬP TRUNG hơn khi NGỒI CODE

Tại sao anh em lại thích nghe nhạc trên Youtube? Câu trả lời đơn giản là trên Youtube nhạc nào mà chả có. Từ nhạc trẻ, nhạc vàng, nhạc đỏ… cho đến rap đều có hết, mà nó lại còn miễn phí nữa. Cứ cắm tai nghe vào là nghe thôi ^^!

Mình không thể phủ định được việc nghe nhạc trên Youtube thực sự rất tiện và hay nữa. Nhưng cái gì cũng có hai mặt của nó.

Bản chất Youtube là nền tảng chia sẻ video, vì vậy có những lúc đang nghe thì tự nhiên thấy bài nhạc bạn nghe bị dừng hoặc bị chèn quảng cáo rất khó chịu.

Ok, bạn có thể cài adblock nhưng cứ mỗi lần lướt ra Youtube để nghe nhạc mình cá là nhiều anh em sẽ “lang thang” thêm vài một video nữa rồi mới sực nhớ ra: “Ơ, đang giờ làm việc mà!”

Vì vậy nếu có điều kiện anh em có thể chọn nghe nhạc theo cách khác, ví dụ như nghe trên spotify hoặc các app nghe nhạc để tránh việc sao nhãng nhé.

Hoặc anh em cũng có thể tải một vài bài nhạc không lời mà anh em yêu thích về máy tính và sau đó bật để nghe khi code. Rất tuyệt vời đấy

#2. Hãy nhớ, 50 phút giải lao một lần !

Đừng quá để ý đến con số 50 phút nha các bạn !

Thực ra, khả năng tập trung của mỗi người là khác nhau, có người ngồi cả ngày được , nhưng có người chỉ ngồi được 20-30 phút là đã cảm thấy khá oải rồi.

5 tips giúp lập trình viên TẬP TRUNG hơn khi NGỒI CODE

Khi làm lập trình, không chỉ bộ não phải hoạt động, mà bạn phải nhìn màn hình liên tục. Điều này nhiều khi khiến bạn mỏi mắt chứ chưa muốn nói là hoa mắt nữa.

Chính vì như vậy mà các bạn nên đưa ra một khoảng thời gian mà các bạn thấy phù hợp để tập trung làm việc trong khoảng thời gian đó. Sau đó nghỉ ngơi một chút rồi lại làm tiếp.

Đừng cố làm việc khi cảm thấy đầu óc đang bị căng thẳng, bởi thời gian đó bạn cũng không làm việc gì nên hồn được đâu. Hãy nghỉ ngơi 1 lát để lấy lại “phong độ” nhé !

Để đưa ra được một con số thích hợp (ví dụ 30′, 40’, 50’ hay là 1 tiếng đồng hồ) thì các bạn phải tự thử nghiệm xem sao.

Tức là bạn hãy thử nghiệm xem bạn có thể TẬP TRUNG LÀM VIỆC được tối đa trong vòng bao lâu, rồi lấy đó làm “con số tập trung” của bạn. Cái này tùy vào khả năng và cơ địa của mỗi người nên mình không thể fix cứng được nha các bạn !

#3. Úp điện thoại, hoặc không để điện thoại gần người

Nếu anh em để điện thoại cạnh người rồi còn bật Wi-Fi nữa thì thôi rồi, tập xác định ! Thông báo cứ ting ting liên tục thì làm sao mà tập trung nổi.

5 tips giúp lập trình viên TẬP TRUNG hơn khi NGỒI CODE

Tất nhiên là không đến mức phải tắt máy hay tắt nguồn, vì nhiều khi có những cuộc gọi quan trọng nên nếu anh em tắt nguồn thì sẽ lỡ mất.

Với mình thì mình thường tắt Wi-Fi đi, lật úp điện thoại xuống bàn và để ở bên trái hoặc phía sau Laptop của mình. Bạn cũng có thể kích hoạt chế độ KHÔNG LÀM PHIỀN trên điện thoại để làm việc hiệu quả hơn.

Làm như vậy sẽ hạn chế việc mình để ý chiếc điện thoại trong khi nếu có cuộc gọi thì mình vẫn không bị lỡ mất.

Mình biết có nhiều anh em kiểu cứ 10-15 phút lại phải cầm điện thoại lên lướt lướt mới chịu được. Nó thành thói quen rồi nên để khắc phục được thì chẳng còn cách nào khác là rèn luyện thôi.

#4. Tạo danh sách công việc phải làm hàng ngày

Mình nghĩ đây là việc quan trọng nhất nếu anh em muốn tập trung thực sự, vì đơn giản chỉ khi lên kế hoạch rồi thì anh em mới định hình được mình phải làm gì, làm khi nào và làm trong bao lâu.

5 tips giúp lập trình viên TẬP TRUNG hơn khi NGỒI CODE

Thực tế khi đi làm thì anh em sẽ được phân làm theo Task, tức là các đầu việc gần như đã rõ ràng rồi. Việc của anh em chỉ là ngồi lại xem cái nào làm trước, cái nào làm sao và làm trong bao lâu mà thôi.

Ngoài ra anh em nào còn có kế hoạch khác (chẳng hạn như ngồi học công nghệ mới, viết tài liệu, họp với sếp…) thì anh em cũng phải sắp xếp sao cho hợp lý.

Khi tất cả nằm trong kế hoạch rồi thì cứ thế mà triển thôi. Mình tin chắc nếu tạo được todo-list như vậy thì anh em sẽ làm việc cực kỳ hiệu quả luôn.

Còn việc tạo todo list sao cho hiệu quả thì mình nghĩ anh em nên tạo theo thứ tự ưu tiên (ưu tiên về mức độ cần hoàn thành của task, ưu tiên những việc phải giải quyết ngay trong ngày).

Với mình, mình luôn làm những công việc “khó nhai” nhất trước, vì thời điểm đầu ngày sẽ là thời điểm dễ tập trung cao độ nhất, sau khi đã hoàn thành việc khó nhất trong ngày rồi thì những việc tiếp theo cứ thong thả mà làm thôi

Nói chung là phải có mục tiêu và kế hoạch rõ ràng, anh em phải định hình được các công việc cần phải làm trong ngày thì mọi việc diễn ra một cách đúng lộ trình hơn…

#5. Kiếm một chỗ ngồi thật thoải mái

5 tips giúp lập trình viên TẬP TRUNG hơn khi NGỒI CODE

Chắc có lẽ, chẳng mấy anh em nghĩ đến việc kiếm một chỗ ngồi thoải mái đâu nhỉ, vì những yếu tố ngoại cảnh như thế ít ai để ý.

Vậy thế nào là một chỗ ngồi thoải mái, theo mình trước tiên phải có cái ghế dễ ngồi đã (ghế có thể thay đổi chiều cao, có tựa lưng chẳng hạn).

Sau đó là đến bàn làm việc, bàn làm việc thì không nên cao quá và phải chắc chắn, cứng cáp (không bị ọt ẹt) và không có mùi gỗ ép.

Vị trí ngồi nên tránh chỗ mọi người đi lại nhiều vì nhiều người đi qua có thói quen tiện tay vỗ vai người ngồi, rất là phiền.

Ngoài ra thì bạn cũng nên để ý đến cả hướng nắng và vị trí điều hòa nữa nhé, vì ngồi sát tường – đúng hướng nắng hoặc đối điện điều hòa thì đều không tốt và dễ khiến bạn có cảm giác khó chịu, gây mất tập trung.

Những yếu tố tuy nhỏ nhặt như vậy thôi nhưng nó có tác động rất lớn đến sự tập trung của anh em đấy !

#6. Lời Kết

Trên đây là 5 kinh nghiệm mà cá nhân mình đang áp dụng để có thể tập trung hơn khi ngồi code, hi vọng nó sẽ giúp ích cho anh em phần nào, chứ thực ra việc tập trung được hay không vẫn là do chính bản thân mỗi người quyết định.

Các yếu tố bên ngoài dù bạn có làm tốt đến đâu mà bản thân bạn không thể tập trung được (không có sự chủ động) thì cũng chẳng có tác dụng gì cả đâu.

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

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

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

Giao thức trong kiểm thử API

Giao thức trong kiểm thử API

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

Bài trước mình đã giải thích vai trò của API đối với client và server, bài này sẽ nói về cách mà 2 thằng đó nói chuyện với nhau (gọi đại khái là 2 cái máy tính cho đơn giản).

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

Protocol là gì?

Giả sử: Có 2 người A và B nói chuyện với nhau qua điện thoại, nếu người A hỏi 1 câu rồi im lặng, người B sẽ biết rằng người A đang chờ đợi câu trả lời và đến lượt người B nói. Hai chiếc máy tính cũng giao tiếp 1 cách lịch sự như vậy và được mô tả với cái thuật ngữ “Protocol” – giao thức.
Giao thức chính là những luật lệ được chấp thuận để 2 cái máy tính có thể nói chuyện với nhau.
Tuy nhiên, luật lệ này chặt chẽ hơn rất nhiều so với giao tiếp giữa người với người. Máy tính sẽ không thông minh để có thể nhận biết 2 câu “A là chồng B” hay “B là vợ A” có cùng ý nghĩa. Để 2 máy tính giao tiếp hiệu quả, server phải biết chính xác cách mà client sắp xếp cái message nó gửi lên như thế nào

Chúng ta đã từng nghe đến những Protocol cho những mục đích khác nhau, ví dụ như Mail có POP hay IMAP, message có XMPP, Kết nối thiết bị: Bluetooth. Trong web thì Protocol chính là HTTP – HyperText Transfer Protocol, vì sự phổ biến của nó mà hầu hết các công ty chọn nó là giao thức cho các API.
Lưu ý: API có thể viết trên nền Protocol khác, ví dụ như SOAP. Nhưng trong khuôn khổ bài viết này, mình chỉ giới thiệu về HTTP.

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

Cuộc sống của HTTP xoay quanh cái vòng luẩn quẩn: Request và Response. Client gửi request, server gửi lại response là liệu server có thể làm được cái client muốn hay ko. Và API được xây dựng trên chính 2 thành phần: Request và Reponse. Trước tiên, ta phải hiểu cấu trúc của mỗi thành phần.

Giao thức trong kiểm thử API

Request

Một cái request đúng chuẩn cần có 4 thứ:

  1. URL
  2. Method
  3. Headers
  4. Body

OK, bây giờ săm soi từng thứ một.

URL là 1 cái địa chỉ duy nhất cho 1 thứ (dùng danh từ), có thể là web page, image,hoặc video. API mở rộng cái ý tưởng gốc của URL cho những thứ khác, ví dụ: customers, products. Và như thế client dễ dàng cho server biết cái nó muốn là cái gì, những cái này còn được gọi chung là “resources” – nguồn lực.

Method: là cái hành động client muốn tác động lên “resources”, và nó thường là động từ. Có 4 loại Method hay được dùng:
– GET: Yêu cầu server đưa lại resource: Hãy tưởng tượng ra cái cảnh vào fb, tay vuốt new feeds.
– POST: Yêu cầu server cho tạo ra 1 resource mới. Ví dụ: đăng ký 1 chuyến đi ở GrabBike.
– PUT: Yêu cầu server cho sửa / thêm vào resource đã có trên hệ thống. Ví dụ: Edit 1 post ở trên fb.
– DELETE: Yêu cầu server cho xóa 1 resourse. Cái này chắc chả cần ví dụ.

Headers: nơi chứa các thông tin cần thiết của 1 request nhưng end-users không biết có sự tồn tại của nó. Ví dụ: độ dài của request body, thời gian gửi request, loại thiết bị đang sử dụng, loại định dạng cái response mà client có đọc được…

Body: nơi chứa thông tin mà client sẽ điền. Giả sử bạn đặt 1 cái bánh pizza, thì thông tin ở phần body sẽ là: Loại bánh pizza, kích cỡ, số lượng đặt.

Response

Sau khi nhận được request từ phía client, server sẽ xử lý cái request đó và gửi ngược lại cho client 1 cái response. Cấu trúc của 1 response tương đối giống phần request nhưng Status code sẽ thay thế cho URL và Method. Tóm lại, nó có cầu trúc 3 phần:

  1. Status code
  2. Headers
  3. Body

Giao thức trong kiểm thử API

Status code là những con số có 3 chữ số và có duy nhất 1 ý nghĩa. Chắc các bạn cũng không còn lạ lẫm với những Error “404 Not Found” hoặc “503 Service Unavailable”. Full list có ở đây. Phần Header và body tương đối giống với request.

Hôm nay tạm vậy đã, hôm sau sẽ tiếp tục.

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

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

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

Lead Engineer trông như thế nào?

Lead Engineer trông như thế nào?

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

Gần đây, anh PM cũ đã hỏi tôi về cách tôi nhìn nhận một người nào đó đủ tiêu chuẩn trở thành Lead Engineer / Tech Lead tương lai. Đây là điều mà tôi chia sẻ và với phản hồi tích cực từ nội bộ, tôi nghĩ nó có thể hữu ích cho các Manager, CTO, Tech Lead, Team lead hay engineer, v.v…

Mặc dù cách đặt title, level và expectations ở mỗi công ty có thể hơi khác một chút, nhưng tôi hy vọng rằng điều này sẽ giúp các engineer phát triển hơn nữa mà tôi đã may mắn được trãi nghiệm.

  Biến Git và GitHub trở thành công cụ đắc lực cho Software Engineer
  Cách Engineer Nhật Bản thực hiện test như thế nào

Tôi nhìn vào năng lực của Lead Engineer được thể hiện trên một số khía cạnh. Lead Engineer có khả năng và kỹ năng của một Senior Engineer. Nhưng hơn thế

  • Hỗ trợ cố vấn, cung cấp hướng dẫn memo, workflow, architect, … để đưa công việc vào guồn trong giai đoạn đầu của quá trình phát triển product / services
  • Hỗ trợ trong kế hoạch phát triển sản phẩm và quy trình.
  • Hỗ trợ team phản hồi với các bên khác liên quan về techical, system.
  • Thảo luận và hỗ trợ các PM, team lead để đảm bảo rằng dev team và technical được lựa chọn phù hợp với target của dự án.

Năng lực của Lead Engineer

Technical

Scope

  • Họ hiểu rõ về các source code, architect, design pattern, các domain liên quan, cách chúng hoạt động, v.v… của một product hoặc 2–5 services (thay đổi tùy theo size S – M – L -XL hé).
  • Họ có khả năng build architect một product / services để đạt được yêu cầuncần thiết cho business.
  • Họ tham gia vào các cuộc trao đổi phát triển sản phẩm để đưa ra các quyết định kỹ thuật tốt với mức độ hiểu biết sâu về tác động của các quyết định đó. Về cơ bản, họ có thể đảm nhận vai trò ra quyết định với khả năng phán đoán hiệu quả dựa trên sự hiểu biết sâu sắc về một product / services và cách chúng sẽ hoạt động.

Hoạt động kỹ thuật

  • Họ có hiểu biết sâu và ngày càng cải tiến hiệu quả cho source code theo quy mô. Mặc dù có thể thay đổi tùy theo bối cảnh của product / services, nhóm hoặc tổ chức, nhưng họ hiểu và áp dụng các quy trình, nguyên tắc để kiểm tra, theo dõi, ghi nhật ký, giám sát và đánh giá tình trạng liên tục develop của product / services một cách hiệu quả.

Con người / Quản lý dự án

Scope

  • Liên quan đến phạm vi giám sát kỹ thuật ở trên, Lead Engineer cũng có khả năng phân chia task hiệu quả thành các phần khả thi cho 3 developer trở lên. Như dựng cấu trúc lớn và chia thành từng phần nhỏ.
  • Xác định phạm vi và trình tự develop một cách hiệu quả bao gồm việc tạo các estimate task thành các phần nhỏ đủ nhỏ để ước tính có hiệu quả, cân nhắc xem ai có thể hoàn thành công việc và thời gian thực hiện công việc đó theo các ràng buộc khác của nhóm.
  • Việc xác định phạm vi này có thể sẽ được phối hợp với các developer khác và team lead. Tuy nhiên, Lead Engineer có kinh nghiệm và khả năng thể hiện trong việc chia task nhỏ, rủi ro từ thành phần khác, xác định các trở ngại tiềm ẩn, v.v… để đảm bảo rằng nó được chia nhỏ một cách hiệu quả và dự án tổng thể là được hiểu một cách rõ ràng.

Estimate

  • Họ thường đạt 70–80% (trong vòng 150% so với ước tính ban đầu) trong việc estimate chính xác Stories/Tasks của họ và hỗ trợ những người khác trong nhóm của họ hoàn thành điều đó.
  • Họ hiểu ticket xác định đúng trông như thế nào, họ viết chúng ra sao để dễ maintain, dễ hiểu khi ticket do một thành viên khác trong nhóm viết cần clear hơn.
  • Các ước tính của họ được hoàn thành một cách nhất quán, đáp ứng các tiêu chí đã xác định DOD (Define Of Done) của team. Điều này bao gồm việc xem xét tất cả các phần của quy trình để đạt được “Hoàn thành”, không chỉ đơn thuần là viết code.
    Dí dụ: Research, Collaboration, Develop, Viết test code, Self check, Deploy, v.v.

Cải tiến team

Cải tiến liên tục

  • Họ luôn đưa ra các ý tưởng để nâng cao hiệu quả công việc của team / department của họ. Về cơ bản, họ đang xem xét mọi thứ một cách tổng thể và xác định các hạn chế, chẳng hạn như họ đang đưa ra các đề xuất về quy trình review, cải thiện các test cases, v.v…
  • Họ có sự hiểu biết ngày càng sâu sắc về product / services, users và business mà nó hoạt động.

Dẫn dắt

  • Họ thể hiện khả năng để những người khác đến với họ một cách tự tin vì họ được biết đến là những người mà những người khác có thể đến để có được cái nhìn sâu sắc hơn, rõ ràng hơn, v.v… về vấn đề nào đó.
  • Họ dẫn dắt những người khác một cách hiệu quả thông qua các cuộc họp, sharing và bất kỳ quy trình nào cần thiết để hoàn thành các mục tiêu của nhóm.

Giao tiếp

  • Họ giao tiếp hiệu quả với những người trong và ngoài nhóm. Đây không phải là năng lực cốt lõi duy nhất, nhưng nó cho phép họ cải thiện hiệu quả team, project, product,… Giao tiếp tốt và rõ ràng, phát triển mối quan hệ với những người trong toàn công ty, cập nhật rõ ràng về các project khác để so sánh project của họ.

Chắc chắn có những năng lực khác cũng quan trọng mà ai đó ở cấp độ này cần: Tư duy về product, Interview, Design Focus, Business Orientation, v.v. và những điều này có thể cực kỳ mạnh mẽ đối với phát triển của các cá nhân.

Tuy nhiên, khi tôi nghĩ về những năng lực cốt lõi mà tôi mong đợi Lead Engineer sẽ được thể hiện. Đây là những điều mà tôi thường xuyên nghĩ đến để giúp các senior engineer tiềm năng thành công và phát triển lên Lead Engineer tại một công ty phần mềm chuyên nghiệp.

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

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

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

Toàn tập về thiết kế Scalable Web Application II

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

Scalable Web Application luôn là điểm quan trọng để đánh giá sự thành công của một web applications. Không còn như xưa, số lương request ít ỏi, nâng ram, nâng chip.

Các ứng dụng ngày nay có thể phải giải quyết hàng tỷ (billion) request hàng ngày. Cùng tìm hiểu cách giải quyết vấn đề qua bài viết dưới đây

18 Web Developer Jobs tốt nhất từ các công ty HOT

1. Giải pháp nào để có Scalable

Với các ứng dụng lớn hiện nay, có Scale được hay không trở thành một câu hỏi lớn. Do nhược điểm hiện hữu về xử lý có hạn của cấu trúc Single Server. Scalable Web Application trở thành bài toán về mặt kiến trúc Architecture.

Toàn tập về thiết kế Scalable Web Application II
Nguồn ảnh / Source: re-cycledair.com

Cần có những giải pháp cụ thể để đảm bảo performance, availability cho ứng dụng. Ngoài ra, khi ứng dụng mở rộng, việc scale là dễ dàng và hiệu quả.

2. Vertical Scaling và Horizontal Scaling

Với một số điểm yếu rõ ràng của kiến trúc Single Server truyền thống. Giải pháp và yêu cầu đặt ra là phải có một mô hình cụ thể cho Scalable Web Application.

Mở rộng theo kiểu Scaling cũng có hai loại Vertical Scaling (theo chiều dọc) và Horizontal Scaling (theo chiều ngang).

2.1 Vertical Scaling

Scale theo chiều dọc được hiểu là

Vertical scaling refers to adding more resources (CPU/RAM/DISK) to your server (database or application server is still remains one) as on demand.

Vertical scaling hiểu như là thêm tài nguyên bổ sung (CPU/RAM/DISK) cho server (hệ cơ sở dữ liệu hoặc server ứng dụng vẫn ở một máy)

Vertical Scaling thường được áp dụng cho các công ty quy mô nhỏ. Các ứng nhỏ khi người dùng tăng đều lên qua thời gian cũng có thể scale theo phương thức này.

Toàn tập về thiết kế Scalable Web Application II
Kiến trúc Single Server thường được scale theo hướng Vertical Scaling

Tuy nhiên, với các ứng dụng có lượt request tới nhiều. Chỉ Single Server là không đủ, rất có thể dẫn tới hiện tượng nghẽn cổ chai. Quá nhiều request nhưng chỉ có một cổng vào.

Nếu chỉ nâng cấp phần cứng, chưa thể có một thiết kế tốt cho Scalable Web Application.

Hơn nữa, Single Server có thể chỉ giải quyết tối đa trong một lúc một số lượng nhất định request. Để improve performance và đảm bảo A trong CAP Theorem. Ta sẽ tìm hiểu kiểu scale tiếp theo

  10 kênh Youtube học lập trình không thể bỏ qua dành cho Junior Web Developer / Designer
  10 trang web hàng đầu để tìm hiểu WordPress

2.2 Horizontal Scaling

Horizontal là theo chiều dọc. Vậy Scalable Web Application được scale theo chiều dọc như thế nào?

Đầu tiên, định nghĩa.

Horizontal Scaling is a must use technology – whenever a high availability of (server) services are required. Scaling horizontally involves adding more processing units or phyiscal machines to your server or database.

Scaling theo chiều dọc nên là scale về công nghê, đảm bảo tính luôn luôn sẵn sàng cho services là điều bắt buộc. Scaling horizontally thường là thêm vào các đơn vị xử lý tính toán hoặc thiết bị phần cứng cho phía server hoặc database

Toàn tập về thiết kế Scalable Web Application II

Về mặt lý thuyết, Horizontal Scaling có thể add thêm nhiều máy vật lý, tuy nhiên một máy vật lý không quá lớn. Các database này được lưu trữ theo kiểu Distributed Storage (lưu trữ phân tán).

3. Phân tích các thành phần của Scalable Web Application

Để có thiết kế tốt và đảm bảo Scalable Web Application, ta cần hiểu rõ từng thành phần trong thiết kế. Tham khảo hình vẽ phía dưới.

  • Client có thể lên tới hàng triệu. Vài triệu request trong một giây đối với các services lớn như Google, Facebook, Amazon
  • CDN là Content Delivery Network, giúp tăng tốc dịch vụ, cải thiện performance. Bạn nào chưa biết có thể tham khảo qua tại đây.
  • Load Balancer giúp cân bằng tải cho phía services, giàn đều số lượng xử lý. Tránh services thì quá nhiều request để handle. Servies lại không có request nào. Kieblog sẽ có bài viết riêng về Load Balancer sau.
  • App server là phần xử lý chung, sẽ phán định xem phần nội dung cần response cho client là lấy từ Memory Cached hay sẽ gọi Workers
  • Job Queue là nơi xử lý tuần tự, FIFO (First in, First out). Request nào tới trước sẽ được xử lý trước, tới sau xử lý sau.
  • Workers là phần xử lý chính của Services, thực hiện tính toán, xử lý, kiểm tra.
  • Distributed Database là hệ cơ sở dữ liệu phân tán (theo mô hình Horizontal Scaling). Có thể tham khảo thêm bài viết về Distributed Cached ở đây

4. Tổng kết

Tùy thuộc vào hệ thống, mục đích và số lượng request phải handle mà bản thân Software Engineer phải lựa chọn kiến trúc phù hợp. Horizontal và Vertical cũng là lý thuyết phụ.

Tuy nhiên, hiểu biết về scale và scaling là chưa bao giờ thừa. Không ai lại muốn viết ứng dụng mà không có khả năng scale hoặc scale rất khó khăn.

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

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

Xem thêm it jobs for Developer hấp dẫn trên TopDev

5 lỗi sai các Web Developers newbie thường mắc phải và cách khắc phục

sai lầm của web developers
5 lỗi sai các Web Developers newbie thường mắc phải và cách khắc phục

Tác giả: Dave Gray

Mục tiêu của bài viết này không phải để khiến bạn cảm thấy xấu hổ hay khó chịu mà là để những người mới bắt đầu có thể tránh việc mắc các sai sót. Sai lầm của Web Developers có thể khiến bạn mất nhiều thời gian và công sức không đáng có.

sai lầm của web developers
5 sai lầm các Web Developers nên tránh

Thứ 5: Thêm dấu cách vào tên file

Bạn có thể lưu tệp HTML của mình với tên “my cool page.html”, nhưng những khoảng trống giữa các từ là một sai lầm.

Địa chỉ web (hay còn gọi là URL) không được có khoảng trắng.

Nếu bạn tải tệp này vào trình duyệt của mình, bạn sẽ thấy “my%20cool%20page.html” trên thanh địa chỉ của trình duyệt. Dấu cách phải được mã hóa vì chúng không được phép trong URL.

Nếu bạn muốn thấy sự phân tách giữa các từ trong tên tệp của mình, hãy sử dụng dấu gạch dưới (my_cool_page.html) hoặc dấu gạch ngang (my-cool-page.html).

Là người mới bắt đầu, bạn có thể không quá lo lắng về việc tối ưu hóa công cụ tìm kiếm (SEO), nhưng Google đã từng đề cập rằng họ thích dấu gạch ngang trong tên tệp hơn dấu gạch dưới.

  10 trang web hàng đầu để tìm hiểu WordPress
  10 tip tối ưu code trên JavaScript mà web developer nào cũng nên biết

Thứ 4: Bỏ qua cAsE sEnSiTiViTy

Nếu bạn đang sử dụng Windows cho công việc của mình, bạn có thể không nhận thấy sự cố khi sử dụng chữ thường và chữ in hoa không nhất quán. Đây cũng là một sai lầm.

Giả sử bạn đã tạo một thư mục CSS có tên “Css” và một tệp bên trong nó có tên “Main.css”. Nhưng trong mã của bạn, bạn liên kết đến nó như thế này:

<link rel="stylesheet" href="css/main.css">

Khi bạn đang thực hiện project của mình sẽ không có vấn đề gì xảy ra. Nhưng khi bạn tải dự án của mình lên một máy chủ web thì sẽ không có CSS ​​nào được áp dụng cả.

Nhiều máy chủ web có một số phiên bản Linux hoặc Unix chạy thay vì Windows. Bạn có thể đã nghe nói về ngăn xếp LAMP. Linux là chữ L trong LAMP.

Các hệ thống này phân biệt chữ hoa chữ thường.

Do đó, cách tốt nhất là sử dụng tên tệp viết thường và tên thư mục mọi lúc, trừ khi có quy ước đặt tên cụ thể sử dụng chữ cái viết hoa. Tại thời điểm đó, tên tệp sẽ vẫn luôn nhất quán. Và sự nhất quán là thứ sẽ ngăn chặn sai lầm này.

Xem thêm Trước khi trở thành Web Developer mình đã phải bỏ lỡ những điều gì?

Thứ 3: Không hiểu Đường dẫn tệp

Đa phần các sinh viên không hiểu cách liên kết các tệp trong các thư mục khác nhau thường kết xuất tất cả các tệp của họ trong thư mục gốc để truy cập chúng. Đây là một sai lầm dẫn đến một file tree không được sắp xếp.

Không lâu sau khi bạn bắt đầu học HTML, bạn bắt đầu học cách liên kết với các tệp HTML và CSS khác.

Điều này khá đơn giản khi các file nằm trong cùng một thư mục. Ngay cả trong ví dụ trên, chúng tôi chỉ xem bên trong thư mục CSS cho tệp main.css. Nó bắt đầu trở nên phức tạp hơn khi chúng ta cần truy cập một thư mục thay vì (hoặc trước đó) đi xuống một thư mục.

Trong ví dụ dưới đây, chúng tôi đang đặt hình nền cho một trang web trong file main.css của chúng tôi. File main.css nằm trong thư mục CSS. Chúng tôi đang liên kết đến một hình ảnh trong thư mục img.

body {
background-image: url("../img/moon.png");
}

Cả hai thư mục này đều nằm trong thư mục gốc. Do đó, cần đi lên và ra khỏi thư mục CSS và sau đó xuống thư mục img. Chúng tôi đi lên một thư mục có hai dấu chấm: “..”

Từ đó, chúng tôi đi xuống thư mục img để liên kết đến tệp moon.png.

Nếu chúng ta cần truy cập hai thư mục, đường dẫn tệp sẽ bắt đầu như sau: “../../”

Hãy nhớ rằng, một dấu chấm cho biết thư mục bạn đang ở. Hai dấu chấm cho biết thư mục phía trên nơi bạn hiện đang ở.

lưu ý web developers

Thứ 2: Không đặt tên cho index trang mặc định

Đặt tên trang mặc định của bạn không phải là “index” là một sai lầm. Máy chủ web tìm kiếm một tệp chỉ mục. Khi bạn đang làm việc với HTML, bạn nên có một tệp index.html. Tệp này sẽ tải theo mặc định mà không hiển thị tên tệp ở cuối URL.

Đó là lý do tại sao bạn có thể truy cập dot com hoặc địa chỉ web khác yêu thích của mình và không thấy “/index.html” sau “.com” của chúng. Tệp chỉ mục tải theo mặc định.

Đúng là, trang web yêu thích của bạn có thể sử dụng nhiều hơn HTML, nhưng khái niệm này được chuyển sang các công nghệ khác như PHP (index.php), React (index.js),…

Khi bạn tiếp tục tìm hiểu, bạn sẽ thấy một số nhà phát triển chọn các tên tệp khác khi sử dụng các công nghệ khác, nhưng là người mới bắt đầu, hãy gắn bó với chỉ mục.

  10 tips để trở thành Java Developer xịn hơn

Thứ 1: Không dành thời gian nghỉ ngơi

Là một giảng viên, tôi đã nhận được nhiều email từ các sinh viên than phiền về việc họ thất vọng như thế nào khi không làm được việc. Họ đã đổ nhiều thời gian cho dự án mà vẫn không thể tìm ra lỗi.

Thông thường, vấn đề là tag hoặc biến sai chính tả, thiếu dấu chấm phẩy hoặc lỗi cú pháp nhỏ khác. Điều này xảy ra với tất cả chúng ta!

Sau khi nhìn chằm chằm vào mã trong một khoảng thời gian dài, tầm nhìn của chúng ta bị mờ đi, bộ não của chúng ta hoạt động khó khăn và những gì có thể dễ dàng nhìn thấy bằng đôi mắt mới trở nên không thể.

Đừng cảm thấy tồi tệ. Đừng tự trách mình. Hãy dành một ít thời gian để nghỉ ngơi. Đi dạo. Uống một ít cà phê. Hay đánh một giấc… Bất cứ điều gì có thể giúp bạn thoát khỏi sự lo lắng và trả lại cho bạn đôi mắt tươi tắn và đầu óc minh mẫn trở lại.

Thực sự, sai lầm này không chỉ dành cho người mới bắt đầu. Nó có thể xảy ra với bất cứ ai. Hãy quay lại làm việc khi bạn đã trở nên fresh hơn và mọi thứ chắc chắn sẽ rõ ràng cũng như dễ chịu hơn!

Bài viết được phỏng dịch theo bài viết gốc tại freecodecamp.org

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

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

Todo App Flutter – Real Code

Todo App Flutter – Real Code

Bài viết được sự cho phép của tác giả Khiêm Lê

Todo App Flutter

Todo App Flutter là một ứng dụng giúp chúng ta có thể lưu lại những công việc cần làm, tránh việc chúng ta quên đi sau một thời gian. Todo app là một ứng dụng khá đơn gian mà ai học qua lập trình di động đều biết và code khi mới bắt đầu, hôm nay chúng ta sẽ cùng thực hiện điều đó.

  Biết chọn gì đây? Flutter, React Native hay Xamarin?
  Custom page transition – Flutter

Trong bài này sẽ có các phần sau:

  • Thiết kế giao diện ứng dụng
  • Thiết lập sqlite database
  • Viết code thực thi

Tạo project named Todo và bắt đầu với phần đầu tiên nào!

Thiết kế giao diện

Ý tưởng ứng dụng như sau: màn hình chính sẽ có một ListView hiện ra tất cả các task, mỗi item thì sẽ có một trailing là một button, nhấn vào sẽ hiện ra PopupMenu có hai tùy chọn là Edit và Delete. Nhấn vào Delete sẽ hiện một AlertDialog xác nhận xóa task đó. Nhấn vào Edit sẽ cho phép mình sửa task đó. Một FAB nhấn vào sẽ đưa mình đến màn hình thêm task. Màn hình thêm task đơn giản chỉ có một TextField để nhập task, một nút save phía trên thanh AppBar. Ok, bắt tay vào code nào.

Màn hình chính

Đầu tiên mình tạo một folder đặt tên là screens nằm trong folder lib. Tiếp theo, tạo một file main_screen.dart – đây chính là file màn hình chính của mình. Trong màn hình chính, mình sẽ có một ListView, một FAB, và một cái AppBar hiện tên ứng dụng. Vậy chúng ta sẽ có code sau:

import 'package:flutter/material.dart';

// Vì sau này mình sẽ lấy dữ liệu từ Database đổ vào ListView
// nên dùng StatefulWidget để có thể thay đổi được UI
class MainScreen extends StatefulWidget {
  // Mình đặt id để xíu nữa mình dùng trong routes
  static const id = 'main_screen';

  
  _MainScreenState createState() => _MainScreenState();
}

class _MainScreenState extends State<MainScreen> {
  
  Widget build(BuildContext context) {
    return Scaffold(
      // Một cái AppBar đơn giản hiển thị tên app
      appBar: AppBar(
        title: Text('Todo App'),
      ),
      // FAB sẽ là biểu tượng Add (ý là add task vào ý)
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        child: Icon(Icons.add),
      ),
      body: ListView.builder(
        // Mình demo với 9 item nha
        // Phần sau mình sẽ lấy data từ database sau
        itemCount: 9,
        itemBuilder: (context, index) {
          // Mỗi item là một ListTile
          return ListTile(
            title: Text('Task $index'),
          );
        },
      ),
    );
  }
}

Mình muốn là mỗi item có trailing là một button, khi nhấn vào nó sẽ show một PopupMenu, mình sẽ chọn sử dụng Widget PopupMenuItem. Mình muốn menu có hai item là Edit và Delete, khi nhấn vào Edit sẽ đưa mình đến màn hình Edit, khi nhấn Delete thì sẽ hiển thị AlertDialog xác nhận. Code của mình như sau:

// ...
          return ListTile(
            title: Text('Task $index'),
            trailing: PopupMenuButton(
              onSelected: (i) {
                if (i == 0) {
                  // Code chuyển sang màn hình edit
                } else if (i == 1) {
                  // Hiện dialog
                  showDialog(
                    context: context,
                    builder: (context) {
                      return AlertDialog(
                        title: Text('Confirm your deletion'),
                        content: Text(
                            'This task will be deleted permanently. Do you want to do it?'),
                        actions: <Widget>[
                          // Nút hủy, nhấn vào chỉ pop cái dialog đi thôi không làm gì thêm
                          FlatButton(
                            onPressed: () {
                              Navigator.pop(context);
                            },
                            child: Text('CANCEL'),
                          ),
                          FlatButton(
                            onPressed: () {
                              // Xóa task...
                              Navigator.pop(context);
                            },
                            child: Text(
                              'DELETE',
                              style: TextStyle(color: Colors.red),
                            ),
                          ),
                        ],
                      );
                    },
                  );
                }
              },
              itemBuilder: (context) {
                return [
                  PopupMenuItem(
                    value: 0,
                    child: Text('Edit'),
                  ),
                  PopupMenuItem(
                    value: 1,
                    child: Text('Delete'),
                  ),
                ];
              },
            ),
          );
// ...

Màn hình thêm task

Trong thư mục screens, mình tạo một file mới tên là add_task_screen.dart. Trong màn hình này, mình muốn trên AppBar có một IconButton save, nút back cũng sẽ được mình Override (mình sẽ giải thích phần này sau). Code của mình như sau:

import 'package:flutter/material.dart';

class AddTaskScreen extends StatefulWidget {
  // Mình đặt id dùng trong routes
  static const id = 'add_task_screen';

  
  _AddTaskScreenState createState() => _AddTaskScreenState();
}

class _AddTaskScreenState extends State<AddTaskScreen> {
  final _taskController = TextEditingController();
  bool _inSync = false;
  String _taskError;

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Add task'),
        backgroundColor: Colors.white,
        leading: IconButton(
          icon: Icon(Icons.arrow_back),
          // Nút back trên appbar sẽ không nhấn được khi đang lưu dữ liệu
          onPressed: !_inSync
              ? () {
                  Navigator.pop(context);
                }
              : null,
        ),
        actions: <Widget>[
          // Tương tự, như nút back tránh trường hợp user nhấn 2 lần
          !_inSync
              ? IconButton(
                  icon: Icon(Icons.done),
                  onPressed: () {
                    
                  },
                )
              : Icon(Icons.refresh),
        ],
        elevation: 0.0,
        textTheme: TextTheme(
          title: Theme.of(context).textTheme.title,
        ),
        iconTheme: IconThemeData(
          color: Colors.black87,
        ),
      ),
      body: WillPopScope(
        // Ngăn nút người dùng nhấn back trên android khi đang lưu dữ liệu
        onWillPop: () async {
          if (!_inSync) return true;
          return false;
        },
        child: Padding(
          padding: EdgeInsets.all(16.0),
          child: TextField(
            controller: _taskController,
            decoration: InputDecoration(
              labelText: 'Task',
              errorText: _taskError,
              border: OutlineInputBorder(),
            ),
          ),
        ),
      ),
    );
  }
}

Giờ đến lượt file main.dart, chúng ta cần phải thêm các màn hình này vào để navigate giữa chúng. File main.dart như sau:

import 'package:flutter/material.dart';

// import screens
import 'screens/main_screen.dart';
import 'screens/add_task_screen.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      initialRoute: MainScreen.id,
      routes: {
        MainScreen.id: (_) => MainScreen(),
        AddTaskScreen.id: (_) => AddTaskScreen(),
      },
    );
  }
}

Giờ chúng ta sẽ sửa lại file main_screen.dart, chúng ta sẽ bắt sự kiện onPress FAB thì đi sang màn hình add task. Code sửa lại như sau:

import 'package:flutter/material.dart';

// import screens
import 'add_task_screen.dart';

// ...
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Navigator.pushNamed(context, AddTaskScreen.id);
        },
        child: Icon(Icons.add),
      ),
// ...

Giờ bạn có thể run app để check thử. Chúng ta sẽ chuyển sang phần tiếp theo là thiết lập sqlite database.

Thiết lập SQLite database

Đầu tiên, tạo một folder mới trong folder lib và đặt tên là models. Trong folder models, bạn tạo một file mới có tên là task.dart, đây sẽ là model data của mình. Code như sau:

class Task {
  // Task đơn giản chỉ cần 1 id và task
  final int id;
  final String task;
  // constructor
  Task({this.id, this.task});

  // function chuyển properties của class Task sang Map để lưu trong database
  Map<String, dynamic> toMap() {
    return {
      'id': id,
      'task': task,
    };
  }
}

Giờ chúng ta đã có model Task, tiếp theo chúng ta cần phải lưu trữ data trong database. Tạo folder có tên database trong folder lib, trong folder database tạo một file mới có tên là tasks_db.dart. Trước khi code trong file này, mình cần phải thêm 2 dependencies là path và sqflite và file pubspec.yaml:

// ...
dependencies:
  flutter:
    sdk: flutter
  path:
  sqflite:
// ...

Nhớ chạy lệnh “flutter pub get” để lấy dependencies nha. Tiếp tục với file tasks_db.dart, mình sẽ có code sau:

import 'dart:async';

import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';

// import Task model
import '../models/task.dart';

class TasksDB {
  Database _database;

  // Mình để các biến final để sau này chỉ cần đổi một chỗ thôi cho tiện
  final String kTableName = 'tasks';
  final String kId = 'id';
  final String kTask = 'task';

  // Hàm mở database
  Future _openDB() async {
    // openDatabase được cung cấp bởi sqflite
    _database = await openDatabase(
      // lấy đường dẫn database, tasks.db là tên file do mình đặt
      join(await getDatabasesPath(), 'tasks.db'),
      onCreate: (db, version) {
        // Truy vấn tạo table khi database được tạo
        return db.execute(
            'CREATE TABLE $kTableName($kId INTEGER PRIMARY KEY AUTOINCREMENT, $kTask TEXT)');
      },
      // Phiên bản của database
      version: 1,
    );
  }

  // Thêm task vào database
  Future insert(Task task) async {
    // Phải chờ mở database trước khi thao tác tiếp
    await _openDB();
    // Thêm task sau khi đã được convert sang Map vào table kTableName
    await _database.insert(kTableName, task.toMap());
    print('Task inserted');
  }

  // Hàm cập nhật task
  Future update(Task task) async {
    await _openDB();
    // Cập nhật lại task tại record có id là id của task truyền vào
    await _database.update(
      kTableName,
      task.toMap(),
      where: '$kId = ?',
      whereArgs: [task.id],
    );
    print('Task updated');
  }

  // Xóa task
  Future delete(int id) async {
    await _openDB();
    // Xóa task có id là id được truyền vào
    print((await _database.delete(
      kTableName,
      where: '$kId = ?',
      whereArgs: [id],
    )));
    print('Task deleted');
  }

  // Lấy toàn bộ task trong database
  Future<List<Task>> getTasks() async {
    await _openDB();
    // Query toàn bộ table kTableName về một List<Map>
    List<Map<String, dynamic>> maps = await _database.query(kTableName);
    // Chuyển List<Map> về dạng List<Task> và return về List đó
    return List.generate(
        maps.length,
        (i) => Task(
              id: maps[i][kId],
              task: maps[i][kTask],
            ));
  }
}

Vậy là chúng ta đã thiết lập xong database. Giờ chúng ta sẽ thực hiện nối UI và code thực thi lại với nhau.

Viết code thực thi

Chúng ta sẽ bắt đầu với file add_task_screen.dart trước. Sẽ có một sự thay đổi lớn ở đoạn này, mình sẽ giải thích trong code. Đoạn code nào được add comment “// new” là mới thêm vào.

import 'package:flutter/material.dart';

import '../database/tasks_db.dart'; // new
import '../models/task.dart'; // new

class AddTaskScreen extends StatefulWidget {
  static const id = 'add_task_screen';

  final Task task; // new

  AddTaskScreen(this.task); // new

  
  _AddTaskScreenState createState() => _AddTaskScreenState();
}

class _AddTaskScreenState extends State<AddTaskScreen> {
  final _taskController = TextEditingController();
  bool _inSync = false;
  String _taskError;

   // new
  void initState() { // new
    Task task = widget.task; // new
    // Nếu có task được truyền qua màn hình add, tức là đang chỉnh sửa task
    if (task != null) { // new
      // Thực hiện gán task vào TextField
      _taskController.text = task.task; // new
    } // new
    super.initState(); // new
  } // new

  void addTask() async { // new
    // Kiểm tra TextField xem có trống hay không
    if (_taskController.text.isEmpty) { // new
      setState(() { // new
        _taskError = 'Please enter this field'; // new
      }); // new
      return null; // new
    } // new
    setState(() { // new
      _taskError = null; // new
      _inSync = true; // new
    }); // new
    final db = TasksDB(); // new
    final task = Task( // new
      task: _taskController.text.trim(), // new
    ); // new
    // insert task vào database
    await db.insert(task); // new
    setState(() { // new
      _inSync = false; // new
    }); // new
    // Trở về màn hình chính với giá trị trả về là true
    Navigator.pop(context, true); // new
  } // new

  void updateTask() async { // new
    if (_taskController.text.isEmpty) { // new
      setState(() { // new
        _taskError = 'Please enter this field'; // new
      }); // new
      return null; // new
    } // new
    setState(() { // new
      _taskError = null; // new
      _inSync = true; // new
    }); // new
    final db = TasksDB(); // new
    // Update task với giá trị mới ở record có id là id của task truyền vào
    final task = Task( // new
      id: widget.task.id, // new
      task: _taskController.text.trim(), // new
    ); // new
    await db.update(task); // new
    setState(() { // new
      _inSync = false; // new
    }); // new
    Navigator.pop(context, true); // new
  } // new

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Add task'),
        backgroundColor: Colors.white,
        leading: IconButton(
          icon: Icon(Icons.arrow_back),
          onPressed: !_inSync
              ? () {
                  Navigator.pop(context);
                }
              : null,
        ),
        actions: <Widget>[
          !_inSync
              ? IconButton(
                  icon: Icon(Icons.done),
                  onPressed: () {
                    // Nếu như có truyền vào task tức là mình update
                    // nếu không thì add task
                    widget.task == null ? addTask() : updateTask(); // new
                  },
                )
              : Icon(Icons.refresh),
        ],
        elevation: 0.0,
        textTheme: TextTheme(
          title: Theme.of(context).textTheme.title,
        ),
        iconTheme: IconThemeData(
          color: Colors.black87,
        ),
      ),
      body: WillPopScope(
        onWillPop: () async {
          if (!_inSync) return true;
          return false;
        },
        child: Padding(
          padding: EdgeInsets.all(16.0),
          child: TextField(
            controller: _taskController,
            decoration: InputDecoration(
              labelText: 'Task',
              errorText: _taskError,
              border: OutlineInputBorder(),
            ),
          ),
        ),
      ),
    );
  }
}

Giờ là đến file main_screen.dart chúng ta có code như sau:

import 'package:flutter/material.dart';

import '../database/tasks_db.dart'; // new
import '../models/task.dart'; // new

// import screens
import 'add_task_screen.dart';

class MainScreen extends StatefulWidget {
  static const id = 'main_screen';

  
  _MainScreenState createState() => _MainScreenState();
}

class _MainScreenState extends State<MainScreen> {
  List<Task> tasks = []; // new

  Future getTasks() async { // new
    // Lấy tất cả task và gán vào list tasks
    final db = TasksDB(); // new
    tasks = await db.getTasks(); // new
    setState(() {}); // new
  } // new

  Future deleteTask(int id) async { // new
    // Xóa task ở record có id là id được truyền vào
    final db = TasksDB(); // new
    await db.delete(id); // new
    tasks = await db.getTasks(); // new
    await getTasks(); // new
    setState(() {}); // new
  } // new

   // new
  void initState() { // new
    getTasks(); // new
    super.initState(); // new
  } // new

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Todo App'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          // Navigate sang màn hình add task và chờ kết quả trả về
          final result = await Navigator.pushNamed(context, AddTaskScreen.id); // Edited
          // Nếu kết quả trả về là true tức là có thêm task nên ta sẽ cập nhật lại list tasks
          if (result == true) getTasks(); // new
        },
        child: Icon(Icons.add),
      ),
      body: ListView.builder(
        itemCount: tasks.length, // Edited
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(tasks[index].task), // Edited
            trailing: PopupMenuButton(
              onSelected: (i) async {
                if (i == 0) {
                  // Tương tự như FAB add task, ta chờ xem có update task thì up
                  // lại list tasks
                  final result = await Navigator.pushNamed( // Edited
                    context,  // new
                    AddTaskScreen.id,  // new
                    // truyền task qua màn hình add task để edit
                    arguments: tasks[index],  // new
                  );  // new
                  if (result == true) getTasks(); // new
                } else if (i == 1) {
                  showDialog(
                    context: context,
                    builder: (context) {
                      return AlertDialog(
                        title: Text('Confirm your deletion'),
                        content: Text(
                            'This task will be deleted permanently. Do you want to do it?'),
                        actions: <Widget>[
                          FlatButton(
                            onPressed: () {
                              Navigator.pop(context);
                            },
                            child: Text('CANCEL'),
                          ),
                          FlatButton(
                            onPressed: () {
                              // delete task có id  là id của item hiện tại
                              deleteTask(tasks[index].id); // new
                              Navigator.pop(context);
                            },
                            child: Text(
                              'DELETE',
                              style: TextStyle(color: Colors.red),
                            ),
                          ),
                        ],
                      );
                    },
                  );
                }
              },
              itemBuilder: (context) {
                return [
                  PopupMenuItem(
                    value: 0,
                    child: Text('Edit'),
                  ),
                  PopupMenuItem(
                    value: 1,
                    child: Text('Delete'),
                  ),
                ];
              },
            ),
          );
        },
      ),
    );
  }
}

Chúng ta đã xong 2 file screen rồi, nhưng nếu bạn để ý bạn sẽ thấy, mình sử dụng Constructor để nhận dữ liệu, vậy làm sao có thể dùng thuộc tính arguments để truyền dữ liệu? Chúng ta sẽ chỉnh sửa lại file main.dart để hoàn thành việc đó. Ta sẽ có code như sau:

      routes: {
        MainScreen.id: (_) => MainScreen(),
        AddTaskScreen.id: (_) => AddTaskScreen(), // Xóa dòng này đi
      },
      // Thêm đoạn code bên dưới vào
      onGenerateRoute: (settings) {
        // Nếu Navigator được gọi và màn hình đến là AddTaskScreen
        if (settings.name == AddTaskScreen.id) {
          return MaterialPageRoute(
            builder: (context) {
              // Nếu có dữ liệu truyền vào thì đưa qua constructor
              if (settings.arguments != null) {
                Task task = settings.arguments;
                return AddTaskScreen(task);
              }
              // default là null
              return AddTaskScreen(null);
            },
          );
        }
        return null;
      },

Tổng kết

Vậy là chúng ta đã viết được một Todo App Flutter đơn giản rồi. Mình đã upload toàn bộ Source code lên github rồi.

Vậy là trong bài này, mình đã code xong app Todo sử dụng Flutter và các plugin Flutter như path, sqflite. Hy vọng bài viết này sẽ có ích cho các bạn, nếu bạn thấy hay có thể share để mọi người cùng đọc. Cảm ơn các bạn đã đọc bài viết của mình!

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

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

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

Chạy Python web app

Chạy Python web app

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

Làm một trang web bằng Python là việc cực kỳ đơn giản, 5-7 dòng code với Flask framework, bạn đã sẵn sàng để khoe website “hello world” với cả trái đất này.

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello PyMi.vn!"

Nhưng sẵn sàng khoe không có nghĩa là đã khoe được. Bạn cần phải tiếp tục vật lộn để mang tuyệt tác ấy đến cho cả thế giới này được biết.

Làm thế nào để cho cả “cộng đồng” cùng xem được website của bạn? Nên nhớ, để website chạy được, phải có một cái máy nào đó luôn chạy code Python mà bạn đã viết. Tự nguyện xung phong bật máy tính của mình 24/7 là một lựa chọn dũng cảm, nhưng nhiều khó khăn và rắc rối và tốn tiền. Vì vậy, tìm một “cái máy khác” hay các dịch vụ hosting/VPS/server để chạy thì khỏe người hơn.

Những người dùng đến từ thế giới PHP sẽ đi tìm ngay Python free hosting, nhưng kết quả sẽ không có gì dùng được, đây không phải PHP. Nên từ khóa “free hosting” sẽ không giúp gì cho bạn cả, trong Python cũng chẳng ai nhắc tới khái niệm này.

Tài liệu của Flask – phần hướng dẫn “triển khai” (deployment) có liệt kê vài lựa chọn phổ biến. Trong đó, đáng kể – tiện lợi – và đơn giản nhất là chạy miễn phí với tài khỏan Heroku – có thể chạy 1 website miễn phí, không yêu cầu thẻ tín dụng hay thanh toán – đủ để bạn chạy 1 trang web Python nhỏ.

Dù Heroku đã có hướng dẫn rất chi tiết với một Django app, bài này sẽ thực hiện deploy một website Flask đơn giản lên Heroku.

  Python: Sự khác nhau giữa List và Tuple?

Tạo tài khoản Heroku miễn phí

Vào trang heroku.com rồi chọn “Sign Up”, điền thông tin, Heroku sẽ gửi mail, mở email và xác nhận.

Chạy Python web app

Cài đặt câu lệnh “heroku”, git

Tải chương trình “heroku” theo hướng dẫn ở https://devcenter.heroku.com/articles/getting-started-with-python#set-up , mỗi hệ điều hành sẽ có cách cài riêng.

Git là chương trình để quản lý code của bạn (và chia sẻ với người khác). Thay vì phải nén các file code vào zip, copy qua lại, dùng FTP như thời năm 2000, thì ngày nay người ta sử dụng git để “copy” code về hay “đưa” code đi. Cài đặt git nằm ngoài phạm vi bài viết này, xem thêm tại vinagit.

Tạo một “heroku app”

Gõ lệnh sau tại thư mục chứa code

$ heroku create
Creating app... done, ⬢ glacial-lowlands-37256
https://glacial-lowlands-37256.herokuapp.com/ | https://git.heroku.com/glacial-lowlands-37256.git

Heroku sẽ yêu cầu bạn nhập tài khỏan, rồi tạo một “app” cho bạn, đồng thời thiết lập git để sẵn sàng “đẩy code lên Heroku”

Các file cần có:

  • requirements.txt – chứa danh sách các thư viện cần cho chương trình. Trong ví dụ này có 2 dòng, flask là web framework ta dùng ở đây, và gunicorn – là chương trình server sẽ chạy code Python.
    flask==0.12.2
    gunicorn
    
  • Procfile – chứa câu lệnh mà heroku sẽ chạy. Trong ví dụ này, heroku sẽ chạy app Flask bằng lệnh gunicorn
    # Procfile
    web: gunicorn app:app --log-file -
    
  • Code Flask webapp nằm trong file app.py hiển thị dòng chữ “Hello PyMi.vn!” khi người dùng vào trang chủ
from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello PyMi.vn!"

Xem đầy đủ code tại pymivn/flask_heroku.

  Selenium WebDriver trên Python

Đưa code lên heroku

Sau khi đã add hết các file cần thiết vào git, gõ lệnh để đưa code (push) lên Heroku,

$ git push heroku master
Counting objects: 8, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (8/8), 701 bytes | 0 bytes/s, done.
Total 8 (delta 1), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Python app detected
remote: -----> Installing python-3.6.2
remote: -----> Installing pip
remote: -----> Installing requirements with pip
remote:        Collecting flask==0.12.2 (from -r /tmp/build_332af31aead5e8121044856aecc9b1ca/requirements.txt (line 1))
remote:          Downloading Flask-0.12.2-py2.py3-none-any.whl (83kB)
remote:        Collecting gunicorn (from -r /tmp/build_332af31aead5e8121044856aecc9b1ca/requirements.txt (line 2))
remote:          Downloading gunicorn-19.7.1-py2.py3-none-any.whl (111kB)
remote:        Collecting itsdangerous>=0.21 (from flask==0.12.2->-r /tmp/build_332af31aead5e8121044856aecc9b1ca/requirements.txt (line 1))
remote:          Downloading itsdangerous-0.24.tar.gz (46kB)
remote:        Collecting Werkzeug>=0.7 (from flask==0.12.2->-r /tmp/build_332af31aead5e8121044856aecc9b1ca/requirements.txt (line 1))
remote:          Downloading Werkzeug-0.12.2-py2.py3-none-any.whl (312kB)
remote:        Collecting Jinja2>=2.4 (from flask==0.12.2->-r /tmp/build_332af31aead5e8121044856aecc9b1ca/requirements.txt (line 1))
remote:          Downloading Jinja2-2.9.6-py2.py3-none-any.whl (340kB)
remote:        Collecting click>=2.0 (from flask==0.12.2->-r /tmp/build_332af31aead5e8121044856aecc9b1ca/requirements.txt (line 1))
remote:          Downloading click-6.7-py2.py3-none-any.whl (71kB)
remote:        Collecting MarkupSafe>=0.23 (from Jinja2>=2.4->flask==0.12.2->-r /tmp/build_332af31aead5e8121044856aecc9b1ca/requirements.txt (line 1))
remote:          Downloading MarkupSafe-1.0.tar.gz
remote:        Installing collected packages: itsdangerous, Werkzeug, MarkupSafe, Jinja2, click, flask, gunicorn
remote:          Running setup.py install for itsdangerous: started
remote:            Running setup.py install for itsdangerous: finished with status 'done'
remote:          Running setup.py install for MarkupSafe: started
remote:            Running setup.py install for MarkupSafe: finished with status 'done'
remote:        Successfully installed Jinja2-2.9.6 MarkupSafe-1.0 Werkzeug-0.12.2 click-6.7 flask-0.12.2 gunicorn-19.7.1 itsdangerous-0.24
remote:
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote:
remote: -----> Compressing...
remote:        Done: 42.8M
remote: -----> Launching...
remote:        Released v3
remote:        https://glacial-lowlands-37256.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/glacial-lowlands-37256.git
 * [new branch]      master -> master

Heroku sẽ tự động cài đặt và chạy code, nó sẽ in ra đường dẫn đến trang web lên màn hình https://glacial-lowlands-37256.herokuapp.com/

hoặc nếu không thấy thì gõ:

heroku open

Câu lệnh sẽ tự mở trang web tại địa chỉ https://glacial-lowlands-37256.herokuapp.com/

Xem kết quả

Chạy Python web app

Chú ý

  • SQlite sẽ không dùng được trên Heroku do Heroku sử dụng công nghệ container (như Docker), mỗi lần deploy lại code, các file được sinh ra sẽ bị xóa hết. File SQLite database sẽ bị xóa sau mỗi lần như vậy.
  • Thay vì dùng SQLite, hãy dùng PostgreSQL. Heroku hỗ trợ 1 free database PostgreSQL – database opensource xịn nhất thế giới, xem thêm tại bài hướng dẫn của Heroku.

Tổng kết

Bài này hướng dẫn chạy một Flask web app đơn giản trên Heroku, cho cả thế giới thấy sản phẩm của bạn.

  • Tài khỏan miễn phí của heroku cho phép bạn chạy 1 website nhỏ 550 tiếng “Dynos” mỗi tháng – nói nôm na thì nếu không có nhiều người vào, thời lượng này sẽ đủ chạy cả tháng – và miễn phí. Bao giờ đòi thu tiền Heroku sẽ báo, đến lúc ấy hãy phải lo.
  • Mỗi tài khoản sẽ chỉ được giới hạn miễn phí 550 giờ một tháng (~ 22 ngày CPU chạy liên tục), nên nói chung thì sẽ chỉ chạy được 1 website / tài khoản.
  • Khi “chạy thật”, hầu hết các Python web app sẽ được chạy trên các “máy ảo”/”server”/”cloud” riêng, người dùng sẽ tự lo cài đặt database, tạo virtualenv, cài requirements và chạy code. Heroku là dịch vụ rất tiện, nhưng rất đắt khi website bắt đầu lớn lên.

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

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

Xem thêm tìm việc python hấp dẫn trên TopDev