Home Blog Page 147

Làm quen với kiến trúc Serverless

Làm quen với kiến trúc Serverless

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

Mười mấy năm về trước, ngày còn đang học đại học, mỗi lần đến ngày đăng ký môn học là mình được nghe điệp khúc hát mãi “server quá tải, số lượng sinh viên tranh nhau vào các lớp có nhiều gái xinh quá đông, quá nguy hiểm, mấy em vui lòng canh 12 giờ đêm, khi ko còn ai lên đăng ký môn học, chúng tôi mới đáp ứng kịp”

  Sập server, làm gì đây?
  Chuỗi chuyên đề độc quyền về Serverless từ Amazon Web Services

Ngày đó Server của trường nằm ở Nguyễn Văn Tráng, phòng server nhỏ như hang thỏ, mà chỉ xài đúng mấy ngày đầu học kỳ, nên thầy trưởng khoa ko thể nào xin ngân sách được để mà nâng cấp 10 mấy con server cho các em sinh viên xài thỏa thích.

Bài toán Server đó giờ được giải quyết ra sao? Serverless

Trước tiên cần khẳng định Serverless không phải là bạn không cần server. Một shop thú nuôi đơn giản, vài ngàn người mua hoa một tháng, làm bằng wordpress bạn sẽ không thấy được lợi ích từ việc sử dụng kiến trúc mới này, không những vậy còn là việc ném một cục tiền cho mấy thằng bán dịch vụ như Amazon

Trang bán thú nuôi, kiến trúc cũ sẽ là thế này

Làm quen với kiến trúc Serverless

Tất cả những logic sẽ nằm ở ứng dụng phía server: từ authentication, page navigation, searching, transaction (code backend đó)

Yêu cầu cần có ngân sách, kế hoạch cụ thể, lắp đặt các hệ thống máy chủ, tìm một chỗ để máy, đảm bảo luôn có điện, luôn mát lạnh, đi dây, chọn nhà cung cấp mạng không bị cá mập cắn…

Nói chung bạn tự làm mọi thứ, hoặc bỏ tiền ra thuê một thằng làm mọi thứ, mà nó còn hay đòi hỏi thêm thắt này kia nọ, vô cùng tốn thời gian, nhân lực, tiền bạc, cơ sở hạ tầng.

Infrastructure as a service – IaaS, các dịch vụ cho thuê mặt bằng ra đời. Đáp ứng nhu cầu tiết kiệm chi phí ở thời điểm đầu, nhưng vẫn có thể bành trướng khi cần.

Bạn hình dung nó như việc mở một quán ăn, phải tìm mặt bằng, tìm người giữ xe, chỗ để xe cho khách, thu hút khách vào ăn, thanh toán, sửa chữa điện, nước… Những thằng IaaS là các trung tâm thương mại, nó lo hết mọi thứ khác, bạn chỉ việc bỏ tiền ra và thuê lại mặt bằng và kinh doanh.

Serverless là gì

Nó như một khái niệm kinh tế học, không có một cách định nghĩa chính xác Serverless là gì! Có thể hiểu theo 2 cách sau

Serverless được dùng để ám chỉ những ứng dụng sử dụng phần lớn (hoặc toàn bộ) dịch vụ “nhà hàng xóm” (third-party), được host trên cloud, cho các vấn đề ở phía server là logic và state (ví dụ trạng thái đăng nhập, một dạng của dịch vụ chăm sóc khách hàng thân thiết). Những ứng dụng để sử dụng (không phải những trang profile công ty, show hiệu ứng bay lượn portfolio, ví dụ như Facebook, ứng dụng đăng ký môn học, hoặc ứng dụng điện thoại bị chửi bới quá trời FaceApp, tức là mô hình này không chỉ áp dụng riêng cho web). Những dịch vụ thường được outsource cho nhà hàng xóm là gì: database có ParseFirebase, authentication có Auth0, AWS Cognito. Mấy nhà này nằm trong khu “Backend as a Service” – BaaS, khi gắn vào hậu tố as a Service bạn có thể biết là nó nằm ở nhà hàng xóm.

Serverless cũng có nghĩa là ứng dụng đó logic server vẫn có, developer vẫn phải viết logic này, tuy nhiên, không giống kiến trúc truyền thống, nó chạy theo cơ chế “tiền trao-cháo múc” (event-trigger), không quan tâm anh bạn có ở chung nhà mình không (stateless compute container). Khái niệm này được @marak trên Twitter gọi là Function as a Service – FaaS, bạn có nhu cầu cắt tóc, gội đầu, uống cafe, đánh giày thì bạn ra tiệm hết, không dùng đồ nhà có sẵn nữa. Hiện tại, AWS Lambda là một trong những platform nổi tiếng nhất khi nói đến FaaS

Giờ nói tới FaaS, nó đang là trend, nó thay đổi cách chúng ta trước đây vẫn nghĩ về kiến trúc dưới server.

Tất cả những ông lớn đều có các sản phẩm BaaS và FaaS, Amazon ServerlessGoogle Cloud Functions for Firebase.

Làm quen với kiến trúc Serverless

Một kiến trúc Serverless nó như thế này

Làm quen với kiến trúc Serverless

  1. Phần authen trước đây được gửi nhà hàng xóm làm (cơ quan nhà nước chuyên cung cấp CMND)
  2. Dữ liệu được đưa một về nhà kho quản lý, kiểu như Tiki bây giờ quá mệt quản lý kho hàng, các cửa hàng nhỏ lẻ tự quản lý kho, Tiki bán được thì chạy tới kho của bên thứ 3 lấy.
  3. Với 2 thay đổi ở trên, điều này có nghĩa là một vài logic đã được nằm ở phía client, thí dụ, user session, bạn sẽ thấy rõ nhất ở các Single Page App chúng ta build, phần logic giao diện cho user đã và chưa đăng nhập nằm ở client – nhà user, những route nào user có thể vào nằm ở code client
  4. Một vài hiển thị, ràng buộc tất nhiên vẫn được server nắm. Thí dụ “search”. Chúng ta có thêm một nhà gọi là “API Gateway”, dịch vụ giao nhận, tất cả các yêu cầu từ client đưa về đây, các anh em HTTP sẽ đi lấy dữ liệu từ kho về cho chúng ta.
  5. Với tính năng đặt hàng, nó do một nhà** khác cung cấp. Những logic khác nhau, được tách và deploy thành những cục* khác nhau như vậy cách tiếp cận của FaaS cũng là cách tiếp cận rất phổ biến trong “Microservices”

Nó sẽ có những lợi ích i chang như Microservices, tất nhiên là có trả giá, có nhiều thứ để kiểm soát và theo dõi hơn, vấn đề bảo mật cũng không phải đơn giản như xưa, nằm ở nhiều nơi quá mà, bài toán đi đi lại tránh kẹt xe giữa các hệ thống khác nhau, biết đâu đi lạc vào chổ nào đó mất CMND luôn !!

Function as a Service

Nãy giờ nói FaaS nhiều quá rồi, giờ “đào sâu” nghiên cứu nó chút. Trích dẫn từ trang Amazon Lambda

AWS Lambda lets you run code without provisioning or managing servers. (1) … With Lambda, you can run code for virtually any type of application or backend service (2) – all with zero administration. Just upload your code and Lambda takes care of everything required to run (3) and scale (4) your code with high availability. You can set up your code to automatically trigger from other AWS services (5) or call it directly from any web or mobile app (6).

Diễn giải đoạn dài ngoằn kia

(1) FaaS là chạy backend code mà không cần quan tâm việc quản lý và bảo trì hệ thống server.

(2) FaaS không yêu cầu một framework hay thư viện cụ thể nào. Các function trên Lambda có thể được viết bằng Javascript, Python, Go, Java, Clojure, Scala, .NET.

(3) Deploy sẽ rất khác với hệ thống truyền thống. Tới *nhà** của FaaS chúng ta đưa đoạn code cho chủ nhà, còn lại chủ nhà làm gì thì làm.

(4) Scale sẽ tự động được chủ nhà làm. Nếu hệ thống cần đáp ứng 1000 request đồng thời, chủ nhà sẽ lo, bạn chỉ cần bơm tiền. Quan trọng nhất, bên cung cấp dịch vụ sẽ quản lý hết toàn bộ resource, xin giấy phép, nói chung là toàn bộ – bạn không cần làm gì với cluster, VM cả.

(5) Cung cấp cơ chế trigger ứng với các event bạn muốn.

(6) Mấy bên cung cấp dịch vụ, cho phép các function này trigger theo những sự kiện HTTP request, như ví dụ là search, và purchase, hoặc gọi trực tiếp lên các API được cung cấp bởi bên cung cấp

Case Study

PhotoVogue trang Vogue của Ý, chạy từ năm 2011, sau một năm chạy, photographer bu vô như kiến, server ở nhà riêng quá tải không chịu nổi.

Giám đốc kỹ thuật quyết định chuyển đổi toàn bộ hệ thống server ở nhà riêng sang AWS trong 3 tháng.

Chạy theo trend này, còn có những cái tên rất phổ biến là Uber, Pokemon Go, Airbnb, Clash of Clans và rất nhiều ứng dụng khác khi số lượng user và real-time data lớn

Những vấn đề mà team PhotoVogue đã gặp

  • Có hơn 130,000 photographer trên khắp thế giới sử dụng hệ thống để đưa ảnh lên, ước tính có khoảng 400,000 ảnh, với dung lượng tối đa mỗi hình là 50MB (bọn này chơi sang nhỉ)
  • Số lượng truy cập ngày càng tăng
  • Trải nghiệm sử dụng của user không tốt, thao tác xử lý quá chậm, up ảnh quá rùa

Với AWS, nó đã giải quyết các vấn đề sau cho PhotoVogue

  • Khả năng scale, dễ maintenance, quản lý chi phí rõ ràng
  • Lưu trữ hình trên Amazon S3
  • Khi up lên Amazon S3, bật trigger sử dụng AWS Lambda function, convert các file này qua gif, jpeg, png, tiff
  • Amazon API Gateway được sử dụng để làm tầng caching của REST API, Amazon CloudFront cho CDN

Làm quen với kiến trúc Serverless

Còn vấn đề nào nữa không, mình hy vọng bạn nào chuyên gia vào chỉ giáo

Tài liệu tham khảo

📜 What is Serverless Architecture? What are its Pros and Cons?

📜 Serverless Architectures

📜 Serverless Architecture: A Comprehensive Guide

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

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

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

Một số nguyên tắc thiết kế UI/UX website

thiết kế UX/UI

Bài viết được sự cho phép của tác giả Đoàn Văn Tuyển

Lâu rồi mình mới quay lại viết, chủ đề mình đã muốn viết từ rất lâu rồi: UI/UX. Mình tự nhận không phải là chuyên gia về UX, nhưng mình có thời gian đọc, tìm hiểu thử nghiệm nên cũng có một số kiến thức để chia sẻ với các bạn. Những gì mình viết ở đây chủ yếu là kiến thức liên quan phần visualization (UX thực tế là một khía cạnh rộng lớn hơn). Như mình suy nghĩ thì UX/UI có một số nguyên tắc cần ghi nhớ: First thing first (ưu tiên cho điều quan trọng nhất), Don’t make me think và Consistent (2 cái đầu trùng với tên 2 quyển sách mình khá thích).

1. First thing first

FTF nghĩa là mình luôn luôn ưu tiên cho những thứ quan trọng nhất. Nghĩa là mình sẽ ưu tiên nhóm khách hàng quan trọng, nhóm tính năng quan trọng, thông tin quan trọng với khách hàng…. Cụ thể những thứ mình nghĩ thì như sau:

1.1 Mobile First:
Hiện tại đa số các website vẫn sử dụng thiết kế cho mobile dạng Responsive (nghĩa là Desktop First — Mobile là ưu tiên sau). Giờ là thời buổi mobile, 80% khách hàng sử dụng mobile. Vậy việc thiết kế riêng cho Mobile là điều cực kỳ quan trọng. Cụ thể phần mobile thì phần cuối mình sẽ có một số ví dụ cụ thể hơn, còn ở đây mình cũng nêu một số ví thứ cần để ý:
Màn hình mobile khá nhỏ nên không thể hiển thị full thông tin như desktop => thế nên cần lựa chọn thông tin nào sẽ hiển thị trên mobile
Màn hình Mobile dạng dọc, chiều ngang khá hạn chế, thế nên các bảng biểu cần đều chỉnh thông tin lọt vào màn hình 320–400 pixel (so với 1366 đến 1920 của PC) hoặc tối thiểu cũng có thể scroll để nhìn được.

1.2 Để ý đến khung nhìn đầu tiên:

Một số nguyên tắc thiết kế UI/UX website

Ví dụ về việc khung nhìn đầu tiên không tốt, những thứ ít quan trọng được show lên ở khung nhìn đầu tiên. Ngoài ra phần khoảng trắng cũng không hợp lý.

Khung nhìn đầu tiên là khung nhìn của người dùng mà người dùng không cần Scroll ngang hoặc scroll xuống. Mình nên đặt những thông tin quan trọng nhất vào khung nhìn này. Thay vì việc đặt một banner quá to (và có thể ít thay đổi) thì nên thu nhỏ lại và đưa thông tin quan trọng lên. Việc này đôi khi cũng không được để ý trên mobile, một số màn hình khi vào chỉ nhìn được giao diện của tab hoặc nhứng thông số filter, trên mobile có thể ẩn bớt một số thành phần ít quan trọng để vùng nhìn đầu tiên có thể thể hiện được nhiều thông tin quan trọng. Vùng nhìn đầu tiên còn đặt biệt quan trọng với màn hình chính / màn hình dashboard.

1.3 Chức năng quan trọng:

Một số nguyên tắc thiết kế UI/UX website

Những menu quan trọng được đưa ra trang chủ, link quan trọng hiện ra luôn thay vì ẩn trong menu.

Một trong những vấn đề cần để ý nữa là chức năng quan trọng cần được dễ dàng điều hướng tới. Ngoài việc menu sắp xếp để sao người dùng dễ dàng tìm được những menu quan trọng nhất. Menu nếu cần có thể để hiển thị thay cho việc giấu đi, chức năng muốn người dùng click nhất thì hiển thị rõ lên. “Call to action” cần làm nổi bật và hiển thị ở vùng nhìn đầu tiên. Menu trên mobile có thể thể hiện luôn thay vì giấu đi trên mobile như đa số các website. Một trong những sai lầm kinh điển phần này là người dùng sử dụng quá nhiều icon mà quên đi text. Đôi khi bản thân icon không thể hiện chính xác thông tin (cùng 1 icon mỗi người có thể có hình dung khác nhau), thế nên khi dùng icon thì mình nên thể hiện cả text để người dùng có thể hiểu được chứ năng.

1.4 Thông tin quan trọng:

Một số nguyên tắc thiết kế UI/UX website

Thông tin quan trọng được đưa lên trên và nhấn mạnh, căn phải số để dễ dàng so sánh

Thông tin quan trọng trên màn hình cần làm nổi bật. Một số những chỗ mình thường là như sau:

  • Trong bảng biểu: Cột tổng xếp lên đầu thay cho cuối, sắp xếp dữ liệu theo thứ tự giảm dần (số to lên trước)
  • Các thông tin muốn nhấn mạnh như giảm giá, giá tiền, status, cảnh báo, CTA… cần highlight để thể hiện rõ (nếu nhiều thứ cần chú ý thì sử dụng nhiều level như in đậm, in hoa, tăng font-size, màu sắc…)
  • Chia nhỏ đoạn văn thành những đoạn ngắn hơn, highlight những thông tin quan trọng.
  • Đưa chữ vào ảnh cũng là một thủ thuật tạo sự chú ý.

  6 câu lệnh linux hay dùng trong phân tích log

2. Don’t make me think

Đây là một trong những quyển sách gối đầu giường cho những người muốn biết về UX. Như tiêu đề bạn đã hình dung ra thứ mình muốn nói trong nguyên tắc này. Phần này có một số ý mình muốn nói:

2.1 Hướng dẫn cho khách hàng mới:
Khách hàng mới thường là nhóm khách hàng bơ vơ nhất, vào một hệ thống hoàn toán mới thường không biết làm gì tiếp theo. Thông thường bạn nên có làm những thứ như sau:

  • Gửi email chào mừng và chia sẻ những nguồn lực hỗ trợ cho họ: Hotline, support mail, link đến Q&A (nếu có), tài liệu liên quan nên đọc….
  • Nên có Tour hướng dẫn trên giao diện hoặc hướng dẫn hiển thị ngay trang dashboard.
  • Các chức năng phức tạp nên sử dụng thiết kế kiểu Wizard để dẫn dắt người dùng.
  • Cá nhân mình nghĩ không nên có tài liệu hướng dẫn đồ sộ, không ai có thời gian đọc chỗ đó. Có chăng chỉ là tài liệu để khi gặp vấn đề thì tra cứu (chứ ko phải để đọc hết).

2.2 Hướng dẫn khi gặp lỗi:
Mỗi khi khách hàng làm gì đó sai (ví dụ nhập thông tin không đúng định dạng) luôn hiển thị thông tin cảnh báo với 2 nội dung: lỗi gặp phải là gì & cách khắc phục thế nào. Đây là một trong những lỗi rất hay gặp khi làm giao diện. Khách hàng rơi vào tình trạng này thường rất hoang mang và không biết làm gì tiếp theo. Một trong những thứ cần để ý nữa là khi khách hàng submit form và bị lỗi, bạn phải khôi phục lại form y hệt thông tin trước khi khách hàng submit. Đặc biệt với form nhiều thông tin thì điều này khiến khách hàng rất ức chế.
Một trong những chú ý nhỏ là mình nên sử dụng hiệu ứng để thể hiện có điều gì đó đã diễn ra. Thay vì âm thầm hiển thị lỗi thì hãy để một số hiệu ứng như: loading, slide down…. để gây chú ý cho người dùng.

Nhiều vị trí tuyển dụng UI UX đang chờ bạn ứng tuyển trên TopDev

3. Consistent

Trong khi 2 nguyên tắc trên liên quan nhiều đến UX, thì nguyên tắc cuối lại liên quan đến UI nhiều hơn. Một trong những nguyên tắc theo mình là quan trọng nhất của UI là sự đồng nhất về thiết kế. Font chữ, khoảng cách, kích thước, màu sắc, vị trí đặt các button… tất cả đều cần sự đồng nhất. Nếu thiết kế dạng Mobile First bạn nên sử dụng thiết kế đã được chuẩn hoá của google (Material design system) hoặc Apple’s Flat Design. Hai Design System này có đầy đủ hướng dẫn cực kỳ chi tiết đến mức bạn chỉ cần đọc và áp dụng là đáp ứng được 90% nhu cầu trang mobile web của bạn. Dù Design System đề cập đến rất nhiều yếu tố nhưng mình xin nói về một số thành phần mình cho rằng quan trọng.

3.1 Typography:
Từ này dịch ra tiếng việt mình không rõ là gì nên để tiếng anh. Typography là nói đến các yếu tố liên quan đến chữ bao gồm: font chữ, in đậm in nghiêng gạch chân, font-size, màu chữ, cách dòng, chia cột chữ, khoảng cách giữa các paragraph….. Thực tế mình đôi khi mình không để ý nhưng tất cả những yếu tố trên khi đặt vào trang web muốn đẹp đều có những tỷ lệ nhất định và quan trọng nhất phải đồng nhất trên các trang. Những content cùng ý nghĩa phải có typography đồng nhất. Các button, status, form input, select đều cần có sử sự tương đồng này. Điều này ảnh hưởng rất lớn đến sự “đẹp” của website.

3.2 Khoảng cách và sự alignment:

Một số nguyên tắc thiết kế UI/UX website

Ví dụ về khoảng cách giữa các khối

Việc chia cột, khoảng cách các dòng, khoảng cách giữa các khối…. tất cả những thiết kế này cần có sự tương đồng giữa các trang. Khoảng cách trong form, khoảng cách tớ hai lề… tất cả những yếu tố này cũng cần có sự tương đồng. Một gợi ý nhỏ mình hay thực hiện ở phần này như sau:

  • Với màn hình điện thoại thì nên để khoảng cách giữa khối chính và hai lề nhỏ (để tăng không gian hiển thị)
  • Hạn chế dùng bo viền, sử dụng hai khối màu khác nhau để phân chia.
  • Khoảng cách giữa khối dạng cột thì nhỏ hơn khoảng cách giữa hai dòng.
  • Khoảng cách giữa hai yếu tố liên quan gần hơn so với khoảng cách giữa hai yếu tố ít liên quan.

3.3 Khoảng trắng (đặc biệt trên mobile).

Ví dụ về việc tận dụng không gian trên Mobile.

Khi thiết kế thì một trong những yếu tố quan trọng là khoảng trắng, đặc biệt quan trọng trên Mobile. Vì màn hình Mobile nhỏ, thế nên bạn chắc không muốn scroll chục màn hình để xem thông tin, do vậy thiết kế trên mobile thường tìm cách làm đầu màn hình. Khoảng trắng trên giao diện nên hạn chế chỉ cần đủ để đáp ứng tính thẩm mỹ.

3.4 Nguyên tắc trình bày các loại dữ liệu khác nhau
Một trong những nguyên tắc có thể có nhiều bạn ít để ý là nguyên tắc trình bày văn bản, đặt biệt là những văn bản trong bảng biểu, mình luôn cố gắng tuân thủ các nguyên tắc này, điều này giúp cho thông tin được hiển thị mạch lạc hơn rất nhiều.

  • Số luôn căng lề phải, sử dụng dấu phẩy/chấm để phân chia số phần ngàn. Nếu có thêm số sau số thập phân thì số lượng chữ số sau số thập phân hiển thị phải luôn bằng nhau ở tất cả các dòng trong cùng 1 cột
  • Sử dụng ký tự (-) thay cho những dòng trắng hoặc số giá trị 0
  • Đặt khoảng trắng chính xác khi bỏ các dấu câu như: (.,:;’)
  • Viết hoa đầu dòng, tiêu đề.
  • … Ngoài ra còn có rất nhiều nguyên tắc để đảm bảo sự đồng nhất, để nhìn, dễ đọc nữa, mỗi team nên có một danh sách cho việc này.

Tóm lại UI/UX là chủ đề dài tập, những gì mình nói ở đây mới chỉ là một phần nhỏ của vấn đề. Mình hy vọng ai đó đọc được bài viết này nếu thấy hay hãy chia sẻ lại cho bạn bè và những người bạn cho rằng cần thiết.

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

Bài viết của mình sử dụng khá nhiều kiến thức mình học được từ buổi trao đổi với Tùng Jacob bên TGDD và những slide của bạn ấy. Mọi người có thể xem thêm thông tin tại những link sau:

https://speakerdeck.com/tungjacob/vi-sao-nen-lua-hoa-website-ban-hang-make-a-website-your-mom-can-use
https://docs.google.com/file/d/0B_tCvYq4ZMQKQWJHTnlNZXVwdjg/edit?filetype=mspresentation
https://speakerdeck.com/tungjacob/ui-workshop-for-team-it-thegiodidong-dot-com
https://docs.google.com/presentation/d/1SCrMeZ83z2P37MkmGn6C6oLGERkN6y7vv-bezo_VBUo/edit
https://drive.google.com/file/d/0B_tCvYq4ZMQKYlNHY29BRWIyaUU/view

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

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

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

Tìm hiểu đơn vị EM và REM

Tìm hiểu đơn vị EM và REM

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

Chắc hẳn không ít các bạn khi code web thường hay cân nhắc việc sử dụng đơn vị như thế nào cho hợp lý mà lại hiệu quả. Nào là code trên desktop rồi khi responsive xuống mobile thì bị vỡ layout, cỡ chữ do đơn vị cố định rồi phải chỉnh css từng thành phần…

Ngoài những đơn vị như px, %, vw, vh, pt… thì trong số đó có 2 đơn vị em và rem luôn làm nhiều bạn nhầm lẫn, chưa nắm rõ nên sử dụng trong việc code khá là khó khăn, trắc trở.

  Dùng Px, Em hay Rem để viết media query
  Làm việc từ xa (remote) - Chính sách nhân sự mới của doanh nghiệp trong mùa dịch

Để giải quyết vấn đề đó nên hôm nay mình xin chia sẻ bài đầu tiên về 2 đơn vị em và rem này nhằm giúp các bạn có thể hiểu rõ và áp dụng chúng vào việc code giao diện ra sao nhé. Trước khi vào demo thì mình xin nhắc lại chút về khái niệm của 2 đơn vị em và rem này nha.

# Khái niệm về đơn vị em và rem

rem: là đơn vị tham chiếu tỷ lệ so với phần tử gốc của website ở đây là thẻ <html> dựa vào giá trị của thuộc tính font-size

em: là đơn vị tham chiếu tỷ lệ so với phần tử cha trực tiếp chứa nó hoặc chính nó dựa vào giá trị của thuộc tính là font-size

Tìm hiểu đơn vị EM và REM
Sơ đồ minh họa sự khác nhau giữa đơn vị em và rem

# Áp dụng thực tế

Mình chắn hẳn nhiều bạn đọc xong và thậm chí coi sơ đồ mà vẫn chưa hiểu lắm. Trước đây mình cũng thế. Và cách tốt nhất để hiểu và nắm rõ chúng đó là bắt tay vào code. Nên ở đây mình có làm 1 demo nho nhỏ để cho các bạn dễ hình dung hơn nè.

Đầu tiên là html như thế này:

<html>
<head><title>Em vs Rem</title></head>
<body>
<div class="box">
  <div class="em">EM</div>
  <div class="rem">REM</div>
</div>
</body>
</html>

Tiếp đến là css:

Ta được kết quả như sau. Bạn vẫn chưa hiểu ? Mình có giải thích chi tiết ở bên dưới cho các bạn

# Giải thích chi tiết

Đầu tiên mình tạo html layout gồm có 1 div có class box bọc ngoài và có 2 div bên trong tương ứng với class em rem  sau đó mình set cho thẻ <html> có thuộc tính font-size là 15px và lần lượt 2 ô là màu đỏ xanh cho các bạn dễ phân biệt.

Cho nên lúc này 1em = 1rem = 15px. Như các bạn nhìn vào demo ở trên thì 2 ô đều bằng nhau là 10(em-rem) x 15px = 150px của mỗi ô.

À có chỗ này sẽ có bạn hỏi là đơn vị em phụ thuộc vào phần tử cha chứa nó chứ có phải thẻ <html> đâu sao mà 1em = 15px ?

Mình xin giải thích là vì do lúc này chính nó(class em) và  phần tử cha chứa nó là thẻ div có class box mình chưa set thuộc tính font-size nên nó sẽ phụ thuộc phần tử lớn hơn ở ngoài đó là thẻ <body> nhưng thẻ <body> cũng chưa set thuộc tính font-size nên nó cứ thế lấy ra ngoài cùng cho tới thẻ <html>. Nên ở trên 1em = 1rem = 15px là theo thẻ <html> đấy.

Tuy nhiên bây giờ mình sẽ set cái thuộc tính font-size của thẻ div có class box là 20px thì chắn chắn sẽ có thay đổi. Các bạn nhìn dưới đây nha.

Ô màu đỏ có đơn vị em sẽ to hơn ban đầu vì như mình đã nói ở trên là đơn vị em phụ thuộc vào giá trị thuộc tính font-size của chính nó hoặc phần tử cha trực tiếp chứa nó. Cho nên lúc này ô màu đỏ sẽ có kích thước là 10em x 20px = 200px.

Còn ô màu xanh(rem) do phụ thuộc vào thẻ <html> nên khi mình thay đổi giá trị font-size của thẻ <html> sang 25px thì ô màu xanh cũng sẽ thay đổi kích thước. Và lúc này giá trị của nó sẽ là 10rem x 25px = 250px. Nhìn vào demo bạn sẽ thấy nó to hơn ban đầu và to hơn ô màu đỏ luôn.

# Lời kết

Có 1 chi tiết nhỏ mình quên nói đó là nếu mình không set giá trị của thuộc tính font-size cho thẻ <html> thì font-size mặc định của thẻ <html> là 16px nha.

Hi vọng với giải thích và ví dụ demo của mình sẽ giúp các bạn dễ dàng hiểu hơn về 2 đơn vị em và rem này. Ở bài sau mình sẽ chia sẻ về cách sử dụng 2 đơn vị này vào dự án nhé. Nếu các bạn có ý kiến gì hay hoặc góp ý thì bình luận để giúp mình cải thiện hơn nha. Cám ơn các bạn đã đọc và chúc các bạn một ngày làm việc tốt lành.

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

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

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

HTTP status code là gì? Danh sách đầy đủ HTTP status code

http status code

Dù có là 1 lập trình viên web hay không, chắc hẳn bạn cũng đã bắt gặp HTTP status code (mã trạng thái HTTP) ít nhất 1 hay nhiều lần rồi đúng không nào?

200, 404, 500… đều là những HTTP status code phổ biến. Thậm chí các truyện vui hay ảnh chế meme về 404 cũng khá nổi tiếng và đầy rẫy trên mạng Internet mà hầu hết bất kỳ ai cũng có thể hiểu được.

HTTP status code là gì - error 404

Vậy thì có bao giờ bạn thắc mắc HTTP status code là gì và ý nghĩa các con số của chúng hay chưa? Hôm nay chúng ta sẽ nói tổng quát 1 chút về HTTP status code và ý nghĩa nằm ẩn sau các con số đó nhé!

HTTP Status Code – Mã trạng thái HTTP là gì?

Khi được nhận và phiên dịch 1 yêu cầu HTTP từ phía client, HTTP status code sẽ được máy chủ cung cấp để đáp ứng yêu cầu đó của họ. Nó bao gồm code từ IETF Request for Comments (RFC), các thông số kỹ thuật khác và 1 số code bổ sung được sử dụng trong 1 số ứng dụng phổ biến của giao thức HTTP.

Chữ số đầu tiên của HTTP status code chỉ định 1 trong 5 loại phản hồi quy chuẩn. Các cụm tin nhắn được hiển thị chỉ mang tính tượng trưng, nhưng cũng có thể cung cấp bất kỳ thông tin bổ sung nào để chúng ta có thể đọc được. Trừ khi có những chỉ định khác, HTTP status code được xem như 1 phần của quy chuẩn HTTP/1.1 (RFC 7231).

Cơ Quan Cấp Số Được Ấn Định Trên Internet (tức IANA hay The Internet Assigned Numbers Authority) chính là nơi duy trì sổ đăng ký chính thức của các HTTP status code.

>>> Xem thêm: HttpOnly Flag và Secure Flag là gì?

Hạng mục các HTTP status code

Tất cả các HTTP status code phản hồi được chia ra thành 5 hạng mục riêng biệt và là các số nguyên có 3 chữ số. Chữ số đầu được dùng để xác định loại phản hồi, trong khi 2 chữ số cuối thì không có bất kỳ vai trò phân loại nào. HTTP status code sẽ cho ta biết liệu 1 yêu cầu HTTP cụ thể đã được hoàn thành thành công hay chưa.

Các ứng dụng hiểu HTTP status code không cần phải biết hết tất cả code, tức là dù code không xác định cũng có cụm từ để chỉ lý do không xác định. Cụm từ này không cho phía client nhiều thông tin nhưng các ứng dụng HTTP đó phải hiểu được nó thuộc 1 trong 5  hạng mục riêng biệt. 5 hạng mục đó bao gồm:

1xx (100 – 199): Information responses / Phản hồi thông tin – Yêu cầu đã được chấp nhận và quá trình xử lý yêu cầu của bạn đang được tiếp tục.

2xx (200 – 299): Successful responses / Phản hồi thành công – Yêu cầu của bạn đã được máy chủ tiếp nhận, hiểu và xử lý thành công.

3xx (300 – 399): Redirects / Điều hướng – Phía client cần thực hiện hành động bổ sung để hoàn tất yêu cầu.

4xx (400 – 499): Client errors / Lỗi phía client – Yêu cầu không thể hoàn tất hoặc yêu cầu chứa cú pháp không chính xác. 4xx sẽ hiện ra khi có lỗi từ phía client do không đưa ra yêu cầu hợp lệ.

5xx (500 – 599): Server errors / Lỗi phía máy chủ – Máy chủ không thể hoàn thành yêu cầu được cho là hợp lệ. Khi 5xx xảy ra, bạn chỉ có thể đợi để bên hệ thống máy chủ xử lý xong.

Danh sách đầy đủ các HTTP status code (code + cụm từ chỉ lý do):

1. Information responses / Phản hồi thông tin:

100 Continue: Phản hồi tạm thời này cho biết rằng mọi thứ tới hiện tại vẫn ổn và phía client nên tiếp tục yêu cầu hay bỏ qua phản hồi nếu yêu cầu đã hoàn tất.

101 Switching Protocol: Code này được gửi để phản hồi header yêu cầu Upgrade từ phía client và cho biết giao thức máy chủ đang chuyển sang.

102 Processing (WebDAV): Code này cho biết rằng máy chủ đã nhận và đang xử lý yêu cầu, nhưng phản hồi vẫn chưa có hiệu lực.

103 Early Hints: Được sử dụng để trả về một số tiêu đề phản hồi trước message HTTP cuối cùng.

2. Successful responses / Phản hồi thành công:

200 OK: Yêu cầu đã thành công. Ý nghĩa của thành công còn phụ thuộc vào phương thức HTTP là gì:

GET: Tài nguyên đã được tìm nạp và được truyền trong nội dung thông điệp.
HEAD: Các header thực thể nằm trong nội dung thông điệp.
PUT hoặc POST: Tài nguyên mô tả kết quả của hành động được truyền trong nội dung thông điệp.
TRACE: Nội dung thông điệp chứa thông báo yêu cầu khi máy chủ nhận được.

201 Created: Yêu cầu đã thành công và kết quả là một tài nguyên mới đã được tạo. Đây thường là phản hồi được gửi sau các yêu cầu POST hoặc một số yêu cầu PUT.

202 Accepted: Yêu cầu đã được nhận nhưng chưa được thực hiện. Yêu cầu này là non-committal, vì không có cách nào trong HTTP để gửi sau đó một phản hồi không đồng bộ cho biết kết quả của yêu cầu. Nó dành cho các trường hợp trong đó 1 quá trình / máy chủ khác xử lý yêu cầu hoặc để xử lý hàng loạt.

203 Non-Authoritative Information: Code phản hồi này có nghĩa là siêu thông tin được trả về không hoàn toàn giống với thông tin có sẵn từ máy chủ gốc, nhưng được thu thập từ phần copy local hay của bên phía thứ 3. Code này chủ yếu được sử dụng để phản chiếu hoặc sao lưu tài nguyên khác. Ngoại trừ trường hợp cụ thể đó, thông thường phản hồi “200 OK” được ưu tiên cho trạng thái này.

204 No Content: Không có nội dung để gửi cho yêu cầu này, nhưng các header có thể hữu dụng. User-agent có thể cập nhật các header đã lưu trong bộ nhớ cache cho tài nguyên này bằng các header mới.

205 Reset Content: Cho user-agent biết để reset document đã gửi yêu cầu này.

206 Partial Content: Code phản hồi này được dùng khi Range header được gửi từ client để yêu cầu chỉ 1 phần của nguồn tài nguyên.

207 Multi-Status (WebDAV): Truyền tải thông tin về nhiều nguồn tài nguyên, đối với các trường hợp mà nhiều status code có thể đều thích hợp.

208 Already Reported (WebDAV): Được sử dụng trong 1 phần tử phản hồi <dav:propstat> để tránh liệt kê nhiều lần các thành viên nội tại của nhiều liên kết vào cùng 1 tập hợp.

226 IM Used (HTTP Delta encoding): Máy chủ đã hoàn thành yêu cầu GET cho nguồn tài nguyên và phản hồi là sự trình bày kết quả của 1 hoặc nhiều thao tác instance được áp dụng cho instance hiện tại.

Xem ngay những tin đăng tuyển lập trình viên HTML mới nhất trên TopDev

3. Redirects / Điều hướng:

300 Multiple Choice: Yêu cầu có thể có nhiều hơn 1 phản hồi khả dụng. User-agent hay user nên chọn 1 trong số đó. (Không có cách chuẩn hóa nào để chọn 1 trong các phản hồi, nhưng HTML liên kết đến các khả năng được khuyến nghị để user có thể chọn.)

301 Moved Permanently: URL của tài nguyên được yêu cầu đã được thay đổi vĩnh viễn. URL mới được đưa ra trong phần phản hồi.

302 Found: Code phản hồi này có nghĩa là URI của tài nguyên được yêu cầu đã được thay đổi tạm thời. Những thay đổi khác trong URI có thể được thực hiện trong tương lai. Do đó, chính URI này sẽ được client sử dụng trong các yêu cầu trong tương lai.

303 See Other: Máy chủ gửi phản hồi này để điều hướng client lấy nguồn tài nguyên tại 1 URI khác với 1 yêu cầu GET.

304 Not Modified: Code này được sử dụng cho mục đích caching. Nó cho client biết rằng phản hồi chưa được điều chỉnh, nên client có thể tiếp tục sử dụng cùng phiên bản phản hồi trong bộ nhớ cache.

305 Use Proxy: Được xác định trong phiên bản trước của HTTP specification để chỉ ra rằng phản hồi được yêu cầu phải được truy cập bằng proxy. Nó được yêu cầu do quan ngại về phần bảo mật liên quan đến cấu hình trong băng tần của proxy.

306 unused: Mã phản hồi này không còn được sử dụng nữa, nó được bảo lưu và chỉ được sử dụng trong phiên bản trước của HTTP/1.1 specification.

307 Temporary Redirect: Máy chủ gửi phản hồi này để điều hướng client tới lấy tài nguyên được yêu cầu tại 1 URI khác với cùng 1 phương thức đã được sử dụng trong yêu cầu trước đó. Code này có cùng ý nghĩa như code phản hồi HTTP 302 Found, ngoại trừ việc user-agent không được thay đổi phương thức HTTP sử dụng: nếu POST được dùng trong yêu cầu đầu tiên, POST phải được sử dụng trong yêu cầu thứ hai.

308 Permanent Redirect: Điều này có nghĩa là tài nguyên hiện được đặt cố định tại 1 URI khác, được chỉ định bởi header Location: HTTP Response. Code này có cùng ý nghĩa như code phản hồi HTTP 301 Moved Permanently, ngoại trừ việc user-agent không được thay đổi phương thức HTTP sử dụng: nếu POST được dùng trong yêu cầu đầu tiên, POST phải được sử dụng trong yêu cầu thứ hai.

4. Client errors / Lỗi phía client:

400 Bad Request: Máy chủ không thể hiểu yêu cầu do cú pháp không hợp lệ.

401 Unauthorized: Cho dù quy chuẩn HTTP chỉ định “unauthorized” (không có thẩm quyền), nhưng nó có nghĩa phản hồi này là “unauthenticated” (chưa được xác thực). Có nghĩa là, client phải các tự xác thực chính mình để nhận được phản hồi đã yêu cầu.

402 Payment Required: Code phản hồi này được dành cho những lần sử dụng trong tương lai. Mục đích ban đầu của việc tạo mã này là sử dụng nó cho các hệ thống thanh toán kỹ thuật số, tuy nhiên status code này rất hiếm khi được sử dụng và không tồn tại quy ước tiêu chuẩn nào.

403 Forbidden: Client không có quyền truy cập vào phần nội dung, nghĩa là nó không được phép, vì vậy máy chủ từ chối cung cấp tài nguyên được yêu cầu. Không giống như 401, danh tính của client đã được máy chủ nhận biết.

404 Not Found:
HTTP status code - error 404

405 Method Not Allowed: Phương thức yêu cầu được máy chủ nhận biết nhưng đã bị vô hiệu hóa và không thể sử dụng được. Ví dụ: 1 API có thể cấm XÓA 1 nguồn tài nguyên. 2 phương thức bắt buộc, GET và HEAD, không bao giờ được vô hiệu hóa và không được trả về code lỗi này.

406 Not Acceptable: Phản hồi này được gửi khi máy chủ web, sau khi thực hiện server-driven content negotiation, không tìm thấy bất kỳ nội dung nào phù hợp với các tiêu chí do user-agent đưa ra.

407 Proxy Authentication Required: Code này tương tự như 401 nhưng việc xác thực là cần thiết để được thực hiện bởi proxy.

408 Request Timeout: Phản hồi này được gửi trên 1 kết nối idle bởi 1 số máy chủ, ngay cả khi không có bất kỳ yêu cầu nào trước đó của client. Có nghĩa là máy chủ muốn tắt kết nối không sử dụng này. Phản hồi này được sử dụng nhiều hơn vì 1 số trình duyệt như Chrome, Firefox 27+ hoặc IE9, sử dụng cơ chế  tiền kết nối HTTP để tăng tốc độ lướt web. Cũng lưu ý rằng 1 số máy chủ chỉ tắt kết nối luôn mà không hề gửi thông báo này.

409 Conflict: Phản hồi này được gửi khi 1 yêu cầu xung đột với trạng thái hiện tại của máy chủ.

410 Gone: Phản hồi này được gửi khi nội dung được yêu cầu đã bị xóa vĩnh viễn khỏi máy chủ, không có địa chỉ chuyển tiếp. Client phải xóa bộ nhớ cache và liên kết của mình tới nguồn tài nguyên. HTTP spectication dự định status code này được sử dụng cho “các dịch vụ khuyến mại, có thời hạn”. Các API không nên bắt buộc phải chỉ ra các tài nguyên đã bị xóa bằng status code này.

411 Length Required: Máy chủ đã từ chối yêu cầu vì trường header Content-Lenghth không được xác định và máy chủ thì yêu cầu chuyện đó.

412 Precondition Failed: Client đã chỉ ra các điều kiện tiên quyết trong các header của nó mà máy chủ không đáp ứng được.

413 Payload Too Large: Thực thể yêu cầu lớn hơn giới hạn do máy chủ xác định, máy chủ có thể đóng kết nối hoặc trả về trường header Retry-After.

414 URI Too Long: URI được yêu cầu bởi client dài hơn mức máy chủ muốn thông dịch.

415 Unsupported Media Type: Định dạng phương tiện của dữ liệu được yêu cầu không được máy chủ hỗ trợ, do đó máy chủ đang từ chối yêu cầu.

416 Range Not Satisfiable: Client yêu cầu một phần của tập tin nhưng máy chủ không thể cung cấp nó. Trước đây được gọi là “Requested Range Not Satisfiable”.

417 Expectation Failed: Máy chủ không thể đáp ứng các yêu cầu của trường Expect trong header.

5. Server errors / Lỗi phía máy chủ:

500 Internal Server Error: Một thông báo chung, được đưa ra khi máy chủ gặp phải một trường hợp bất ngờ, message cụ thể không phù hợp.

501 Not Implemented: Máy chủ không công nhận các phương thức yêu cầu hoặc không có khả năng xử lý nó.

502 Bad Gateway: Máy chủ đã hoạt động như một gateway hoặc proxy và nhận được một phản hồi không hợp lệ từ máy chủ nguồn.

503 Service Unavailable: Máy chủ hiện tại không có sẵn (hiện đang quá tải hoặc bị down để bảo trì). Đây chỉ là trạng thái tạm thời.

504 Gateway Timeout: Máy chủ đã hoạt động như một gateway hoặc proxy và không nhận được một phản hồi từ máy chủ nguồn.

505 HTTP Version Not Supported: Máy chủ không hỗ trợ phiên bản “giao thức HTTP”.

Danh sách được tổng hợp và tham khảo từ WikipediaMozilla.

Truy cập ngay các công việc IT đãi ngộ tốt trên TopDev

Vì sao IT Fresher không thể bỏ lỡ Vòng Loại cuối cùng của TopDev Challenge?

TopDev Challenge lần đầu tiên khởi động vào tháng 10/2020 kết hợp cùng nền tảng Hackerrank hứa hẹn một sân chơi chuyên nghiệp, công bằng, trực quan không cảm tính hay thiên vị dành riêng cho lập trình viên sẵn sàng đương đầu thử thách!

Nếu đây từng là nơi “luyện code” nay đã trở thành một đấu trường cạnh tranh năng lực cùng những món quà hấp dẫn “dân công nghệ” không tài nào bỏ qua!

Hiện tại cuộc thi đã đi đến được Round 2 – Vòng Loại cuối cùng của TopDev Challenge 2020 trước khi bước vào Final Round và tìm ra người thắng chung cuộc! 

HackerRank là một nền tảng hiện đang được nhắc đến rất nhiều trong cộng đồng lập trình viên. Nếu bạn đã từng nghe thoáng qua cái tên này hoặc nếu bạn đã biết đến HackerRank nhưng vẫn chưa có “đủ động lực” để thử sức với một nền tảng mà sẽ giúp năng cao kỹ năng lập trình của mình thì hãy cùng TopDev tìm hiểu 4 lý do vì sao bạn nên tạo một tài khoản HackerRank ngay bây giờ nhé!


HackerRank là nơi bạn có thể học và rèn luyện kỹ năng lập trình, đặc biệt về thuật toán, Machine learning & AI, với độ khó từ mức cơ bản cho đến cực kỳ “hack não”.

Trên HackerRank, người tham gia được yêu cầu đưa ra lời giải cho các challenge (những bài toán/câu đố do HackerRank cung cấp). Kết quả và tốc độ giải đề của bạn sẽ những yếu tố để đánh giá và xếp hạng các lập trình viên tham gia trên toàn thế giới!

Hiện tại nhiều công ty công nghệ trên thế giới đang sử dụng HackerRank như một công cụ để đánh giá ứng viên trong quy trình tuyển dụng IT. Riêng Việt Nam cũng sẽ không ngoại lệ, làn sóng sử dụng HackerRank như một bài test ứng viên IT sẽ trở nên phổ biến trong thời gian tới!

Một nơi để bạn khẳng định bản thân và giành lấy những phần quà hấp dẫn thông qua các cuộc thi! Nếu bạn là người “mới vào nghề” (fresher hoặc sinh viên CNTT), việc luyện tập & tham gia một cuộc thi trên HackerRank sẽ là một cơ hội giúp bạn khẳng định bản thân trước nhà tuyển dụng và trong cộng đồng lập trình, đồng thời rinh về những phần quà giá trị!

  HackerRank là gì? Lời khuyên khi tham gia HackerRank

  Ra mắt Nền tảng kết hợp tuyển dụng và đánh giá ứng viên IT chuẩn quốc tế đầu tiên tại Việt Nam TopDev x HackerRank

Không những thế, ciệc lộ diện danh tính các ‘Problem Setter’ có giúp bạn đoán được phần nào chủ đề bài thi:

TopDev Challenge là một “sân chơi chuẩn quốc tế” dành riêng cho IT freshers Việt Nam. Cuộc thi vừa là một nơi “luyện code”, đồng thời cũng là nơi “đọ code” giữa các fresher để bạn có thể khẳng định bản thân trước nhà tuyển dụng nói riêng và trong cộng đồng lập trình viên Việt Nam nói chung. Người chiến thắng còn có cơ hội nhận được những phần thưởng lên đến hàng chục triệu đồng, ngại gì mà không thử sức?!

Tìm hiểu & đăng ký tham gia cuộc thi ngay nào coders ơi!     

Xây dựng REST API cơ bản trong Golang

Xây dựng REST API cơ bản trong Golang

Bài viết được sự cho phép của tác giả Võ Xuân Phong

Để tiếp cận với Golang một cách nhanh chóng hơn, chúng ta sẽ xây dựng một REST API cơ bản với Golang nhé.

Cấu trúc project

Chúng ta hãy tạo cấu trúc thư mục như hình bên dưới, project này có tên GolangRestApi các bạn có thể clone về với đường link sau: Github

  Chiến trường sinh tử phiên bản lập trình : Python vs Ruby vs Golang
  Channel trong Golang là gì? So sánh Callback function và mutex lock với channel

Sau khi clone về các bạn nhớ đổi tên project thành GolangRestApi và vào GOPATH rồi copy vào thư mục src, cách cài đặt và setup dự án Golang các bạn có thể tham khảo chi tiết tại bài viết này của mình:

https://anhlamweb.com/bai-viet-64/hoc-golang-tu-con-so-0-phan-1-cai-dat-golang-tren-linux-va-windows.html

Xây dựng REST API cơ bản trong Golang

Code Rest Api Golang

entities/user.go

Khai báo cấu trúc của một thực thể User. User sẽ có hàm ToString để xuất thông tin chi tiết của User đó ra.

package entities

import (
"fmt"
)

type User struct {
Id string `json:"id"`
Name string `json:"name"`
Password string `json:"password"`
}

func (user User) ToString() string {
return fmt.Sprintf("id: %s\nName: %s\nPassword: %s\n", user.Id, user.Name, user.Password)
}

models/userModel.go

Định nghĩa các hàm cơ bản như CreateUser, UpdateUser, FindUser, DeleteUser và GetAllUser. listUser dùng để chưa thông tin của các User, thay vì để khai báo listUser như vậy chúng ta có thể connect tới  database và thực hiện các thao tác như trên, nhưng để dễ hiểu và rõ ràng hơn thì ở bài viết này chúng ta sẽ thực hiện theo cách đơn giản này trước.

package models

import (
"GolangRestApi/entities"
"errors"
)

var (
listUser = make([]*entities.User, 0)
)

func CreateUser(user *entities.User) bool {
if user.Id != "" && user.Name != "" && user.Password != "" {
if userF, _ := FindUser(user.Id); userF == nil {
listUser = append(listUser, user)
return true
}
}
return false
}

func UpdateUser(eUser *entities.User) bool {
for index, user := range listUser {
if user.Id == eUser.Id {
listUser[index] = eUser
return true
}
}
return false
}

func FindUser(id string) (*entities.User, error) {
for _, user := range listUser {
if user.Id == id {
return user, nil
}
}
return nil, errors.New("User does not exist")
}

func DeleteUser(id string) bool {
for index, user := range listUser {
if user.Id == id {
copy(listUser[index:], listUser[index+1:])
listUser[len(listUser)-1] = &entities.User{}
listUser = listUser[:len(listUser)-1]
return true
}
}
return false
}

func GetAllUser() []*entities.User {
return listUser
}

apis/userapi/userApi.go

Ở file này là các hàm xử lý các http request và chịu trách nhiệm trả về kết quả cho người dùng bằng http response.

package userapi

import (
"GolangRestApi/entities"
"GolangRestApi/models"
"encoding/json"
"net/http"
)

func FindUser(response http.ResponseWriter, request *http.Request) {
ids, ok := request.URL.Query()["id"]
if !ok || len(ids) < 1 {
responseWithError(response, http.StatusBadRequest, "Url Param id is missing")
return
}
user, err := models.FindUser(ids[0])
if err != nil {
responseWithError(response, http.StatusBadRequest, err.Error())
return
}
responseWithJSON(response, http.StatusOK, user)
}

func GetAll(response http.ResponseWriter, request *http.Request) {
users := models.GetAllUser()
responseWithJSON(response, http.StatusOK, users)
}

func CreateUser(response http.ResponseWriter, request *http.Request) {
var user entities.User
err := json.NewDecoder(request.Body).Decode(&user)
if err != nil {
responseWithError(response, http.StatusBadRequest, err.Error())
} else {
result := models.CreateUser(&user)
if !result {
responseWithError(response, http.StatusBadRequest, "Could not create user")
return
}
responseWithJSON(response, http.StatusOK, user)
}
}

func UpdateUser(response http.ResponseWriter, request *http.Request) {
var user entities.User
err := json.NewDecoder(request.Body).Decode(&user)
if err != nil {
responseWithError(response, http.StatusBadRequest, err.Error())
} else {
result := models.UpdateUser(&user)
if !result {
responseWithError(response, http.StatusBadRequest, "Could not update user")
return
}
responseWithJSON(response, http.StatusOK, "Update user successfully")
}
}

func Delete(response http.ResponseWriter, request *http.Request) {
ids, ok := request.URL.Query()["id"]
if !ok || len(ids) < 1 {
responseWithError(response, http.StatusBadRequest, "Url Param id is missing")
return
}
result := models.DeleteUser(ids[0])
if !result {
responseWithError(response, http.StatusBadRequest, "Could not delete user")
return
}
responseWithJSON(response, http.StatusOK, "Delete user successfully")
}

func responseWithError(response http.ResponseWriter, statusCode int, msg string) {
responseWithJSON(response, statusCode, map[string]string{
"error": msg,
})
}

func responseWithJSON(response http.ResponseWriter, statusCode int, data interface{}) {
result, _ := json.Marshal(data)
response.Header().Set("Content-Type", "application/json")
response.WriteHeader(statusCode)
response.Write(result)
}

Main.go

Để xây dựng một REST Api Server thì ở đây chúng ta sử dụng mux và tạo một router để nó thực hiện việc handle request như sau.

Server sẽ lắng nghe ở port 5000.

package main

import (
"GolangRestApi/apis/userapi"
"net/http"

"github.com/gorilla/mux"
)

func main() {
router := mux.NewRouter()

router.HandleFunc("/api/v1/user/find", userapi.FindUser).Methods("GET")
router.HandleFunc("/api/v1/user/getall", userapi.GetAll).Methods("GET")
router.HandleFunc("/api/v1/user/create", userapi.CreateUser).Methods("POST")
router.HandleFunc("/api/v1/user/update", userapi.UpdateUser).Methods("PUT")
router.HandleFunc("/api/v1/user/delete", userapi.Delete).Methods("DELETE")

err := http.ListenAndServe(":5000", router)
if err != nil {
panic(err)
}
}

Chạy chương trình bằng lệnh

go run main.go

Kiểm Tra Kết Quả

Để kiểm tra kết quả chúng ta sẽ sử dụng Postman nhé, bạn có thể vào thư mục assets và import file GolangRestApi.postman_collection.json vào để test cho nhanh.

Tạo mới User.

Xây dựng REST API cơ bản trong Golang

Lấy danh sách các User

Xây dựng REST API cơ bản trong Golang

Tìm kiếm một User

Xây dựng REST API cơ bản trong Golang

Cập nhật User

Xây dựng REST API cơ bản trong Golang

Sau khi update user chúng ta hãy kiểm tra lại thông tin vừa được update.

Xây dựng REST API cơ bản trong Golang

Xóa một User

Xây dựng REST API cơ bản trong Golang

Sau khi delete user chúng ta hãy kiểm tra lại danh sách, như hình bên dưới sau khi delete user đi thì danh sách là rỗng.

Xây dựng REST API cơ bản trong Golang

Tổng kết:

Chúng ta đã tập làm quen với Golang và Rest Api trong Golang, ở bài tiếp theo chúng ta sẽ tìm hiểu tiếp về xác thực Rest Api sử dụng Json Web Token nhé.

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

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

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

Viết chương trình Xoá các File trùng lặp bằng Python

Viết chương trình Xoá các File trùng lặp bằng Python

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

Bạn quá lo âu vì có nhiều file bị trùng lặp trên ổ đĩa khiến chiếm dung lượng bộ nhớ? Nhưng khi tìm kiếm và xoá chúng theo cách thủ công lại quá tẻ nhạt. Tiếp tục Seri python, hôm nay, mình sẽ tiếp tục hướng dẫn các bạn cách xoá các File trùng lặp và giải phóng dung lượng ổ đĩa bằng python.

Giải pháp

Thay vì tìm kiếm khắp ổ đĩa để xoá các File trùng lặp, bạn có thể tự động hóa quy trình này bằng cách sử dụng script, bằng cách viết một chương trình để tìm kiếm đệ quy trong ổ đĩa và loại bỏ tất cả các File trùng lặp được tìm thấy.

Nguyên lý hoạt động

Nếu chúng ta đọc toàn bộ File và sau đó so sánh nó với các File còn lại bằng đệ quy thì sẽ mất rất nhiều thời gian, vậy chúng ta phải làm thế nào mới được?

Câu trả lời là hashing (băm), với hashing chúng ta có thể tạo ra một chuỗi các chữ cái và số nhất định đóng vai trò là danh tính của một File nhất định và nếu chúng ta tìm thấy bất kỳ File nào khác có cùng danh tính, chúng ta sẽ xóa nó.

Viết chương trình Xoá các File trùng lặp bằng Python

Có rất nhiều thuật toán hashing khác nhau như:

  • md5
  • sha1
  • sha224, sha256, sha384 và sha512
  Tại sao phải chọn giữa R hay Python trong khi bạn có thể chọn cả 2?

Code xoá các File trùng lặp bằng Python

Hashing trong Python khá đơn giản, chúng ta sẽ sử dụng thư viện hashlib được mặc định với thư viện chuẩn của Python.

Dưới đây là một ví dụ về cách chúng ta hashing nội dung bằng cách sử dụng hashlib, chúng ta sẽ băm một chuỗi trong Python bằng cách sử dụng thuật toán băm md5.

Ví dụ

>>> import hashlib
>>> example_text = "Duplython is amazing".encode('utf-8')
>>> hashlib.md5(example_text).hexdigest()
'73a14f46eadcc04f4e04bec8eb66f2ab'

Giải thích chút, bạn chỉ cần import hashlib và sau đó sử dụng phương thức md5 để tạo hash và cuối cùng sử dụng hexdigest để tạo chuỗi hash.

Ví dụ trên đã cho chúng ta thấy cách băm một chuỗi nhưng khi xem xét mối việc này với dự án sắp thực hiện, thì chúng ta phải quan tâm đến các File hơn là chuỗi đúng không? Một câu hỏi khác đã được đặt ra.

Chúng ta Hash file như thế nào?

Các File hash (băm) tương tự như chuỗi băm nhưng lại có một sự khác biệt nhỏ, trong quá trình băm File, trước tiên chúng ta cần mở File ở dạng nhị phân và sau đó băm giá trị nhị phân của File.

Băm file

Giả sử bạn có tài liệu văn bản đơn giản trên thư mục dự án của mình với tên learn.txt. Đây là cách mà chúng ta sẽ thực hiện.

>>> import hashlib
>>> file = open('learn.txt', 'rb').read()
>>> hashlib.md5(file).hexdigest()
'0534cf6d5816c4f1ace48fff75f616c9'

Hàm này sẽ trả ra các giá trị băm giống nhau nếu các file đó có nội dung giống nhau khi đó dễ dàng tìm và Xoá các File trùng lặp bằng Python. Lưu ý: khác tên nhưng giống nội dung thì vẫn trả ra giá trị băm giống nhau nhé.

Thách thức nảy sinh khi chúng ta cố gắng đọc một File khá lớn sẽ mất một lúc để tải nó. Do đó, thay vì đợi toàn bộ File vào bộ nhớ, chúng ta có thể tiếp tục tính toán hàm băm khi đọc File.

Việc tính toán hàm băm trong khi đọc File yêu cầu chúng ta đọc File theo các khối có kích thước nhất định và liên tục cập nhật các hàm băm khi chúng ta tiếp tục đọc File cho đến khi băm hoàn chỉnh toàn bộ File. Nói đơn giản là chia file làm nhiều phần, sau đó đọc từng phần, từng phần đó sẽ được hash, sau khi hash sẽ được update vào biến khác.

Làm theo cách này có thể giúp chúng ta tiết kiệm rất nhiều thời gian chờ đợi mà chúng ta có thể sử dụng để đợi toàn bộ File sẵn sàng.

Ví dụ

>>> import hashlib
>>> block_size = 1024
>>> hash = hashlib.md5()
>>> with open('learn.txt', 'rb') as file:
... block = file.read(block_size)
... while len(block)>0:
... hash.update(block)
... block = file.read(block_size)
... print(hash)
...
0534cf6d5816c4f1ace48fff75f616c9

Nhưng băm chỉ là một bước chúng ta cần để thực sự loại bỏ các bản sao, do đó chúng ta sẽ sử dụng module OS để xóa các bản sao.

Chúng ta sẽ sử dụng hàm remove() trong module OS để xoá các File trùng lặp.

Sử dụng module OS để xoá file learn.txt

Ví dụ:

>>> import os
>>> os.listdir()
['Desktop-File-cleaner', '.git', 'learn.txt', 'app.py', 'README.md']
>>> os.remove('learn.txt')
>>> os.listdir()
['Desktop-File-cleaner', '.git', 'app.py', 'README.md']

Sau khi đã xoá được file với hàm remove(), chúng ta sẽ bắt đầu xây dựng ứng dụng.

  Top 15 câu hỏi phỏng vấn Python lý thuyết + thực hành

Cách tạo ứng dụng xoá các File trùng lặp

Những thư viện cần thiết:

import time
import os
from hashlib import sha256

Mình là một người rất thích lập trình hướng đối tượng nên trong bài viết này, mình sẽ xây dựng tool dưới dạng một class duy nhất, code bên dưới chỉ là khung sườn của chương trình.

import time
import os
from hashlib import sha256

class Duplython:
def __init__(self):
self.home_dir = os.getcwd(); self.File_hashes = []
self.Cleaned_dirs = []; self.Total_bytes_saved = 0
self.block_size = 65536; self.count_cleaned = 0

def welcome(self)->None:
print('******************************************************************')
print('**************** DUPLYTHON ****************************')
print('********************************************************************\n\n')
print('---------------- WELCOME ----------------------------')
time.sleep(3)
print('\nCleaning .................')

def main(self)->None:
self.welcome()

if __name__ == '__main__':
App = Duplython()
App.main()

Đó chỉ là giao diện của chương trình, khi bạn chạy nó sẽ chỉ in lời chào mừng ra màn hình.

$ python3 app.py
******************************************************************
**************** DUPLYTHON ****************************
********************************************************************

---------------- WELCOME ----------------------------
​
Cleaning .................

Bây giờ chúng ta sẽ tạo một hàm đơn giản dùng để băm một File với đường dẫn nhất định bằng cách sử dụng kiến ​​thức băm mà chúng ta đã học ở trên.

import time
import os
from hashlib import sha256

class Duplython:
def __init__(self):
self.home_dir = os.getcwd(); self.File_hashes = []
self.Cleaned_dirs = []; self.Total_bytes_saved = 0
self.block_size = 65536; self.count_cleaned = 0

def welcome(self)->None:
print('******************************************************************')
print('**************** DUPLYTHON ****************************')
print('********************************************************************\n\n')
print('---------------- WELCOME ----------------------------')
time.sleep(3)
print('\nCleaning .................')

def generate_hash(self, Filename:str)->str:
Filehash = sha256()
try:
with open(Filename, 'rb') as File:
fileblock = File.read(self.block_size)
while len(fileblock)>0:
Filehash.update(fileblock)
fileblock = File.read(self.block_size)
Filehash = Filehash.hexdigest()
return Filehash
except:
return False

def main(self)->None:
self.welcome()

if __name__ == '__main__':
App = Duplython()
App.main()

Triển khai logic cho chương trình

Sau khi tạo hàm băm File, chúng ta phải triển khai ở nơi sẽ so sánh các chuỗi băm đó và loại bỏ bất kỳ bản sao nào được tìm thấy.

Tôi sẽ tạo một hàm đơn giản được gọi là clean () như hình bên dưới.

import time
import os
from hashlib import sha256
​
class Duplython:
def __init__(self):
self.home_dir = os.getcwd(); self.File_hashes = []
self.Cleaned_dirs = []; self.Total_bytes_saved = 0
self.block_size = 65536; self.count_cleaned = 0
​
def welcome(self)->None:
print('******************************************************************')
print('**************** DUPLYTHON ****************************')
print('********************************************************************\n\n')
print('---------------- WELCOME ----------------------------')
time.sleep(3)
print('\nCleaning .................')

def generate_hash(self, Filename:str)->str:
Filehash = sha256()
try:
with open(Filename, 'rb') as File:
fileblock = File.read(self.block_size)
while len(fileblock)>0:
Filehash.update(fileblock)
fileblock = File.read(self.block_size)
Filehash = Filehash.hexdigest()
return Filehash
except:
return False
​
def clean(self)->None:
all_dirs = [path[0] for path in os.walk('.')]
for path in all_dirs:
os.chdir(path)
All_Files =[file for file in os.listdir() if os.path.isfile(file)]
for file in All_Files:
filehash = self.generate_hash(file)
if not filehash in self.File_hashes:
if filehash:
self.File_hashes.append(filehash)
#print(file)
else:
byte_saved = os.path.getsize(file); self.count_cleaned+=1
self.Total_bytes_saved+=byte_saved
os.remove(file); filename = file.split('/')[-1]
print(filename, '.. cleaned ')
os.chdir(self.home_dir)

def main(self)->None:
self.welcome();self.clean()
​
if __name__ == '__main__':
App = Duplython()
App.main()

Bây giờ chương trình của chúng ta đã gần hoàn tất, việc cuối cùng là phải hiển thị kết quả của quá trình dọn dẹp cho người dùng xem.

Xem thêm:  Javascript Hoa mai đào rơi trang trí Tết cho Website

Mình đã tạo ra hàm Cleaning_summary() chỉ để làm việc đó. In kết quả của quá trình dọn dẹp ra màn hình để hoàn thành chương trình.

import time
import os
import shutil
from hashlib import sha256

class Duplython:
def __init__(self):
self.home_dir = os.getcwd(); self.File_hashes = []
self.Cleaned_dirs = []; self.Total_bytes_saved = 0
self.block_size = 65536; self.count_cleaned = 0

def welcome(self)->None:
print('******************************************************************')
print('**************** DUPLYTHON ****************************')
print('********************************************************************\n\n')
print('---------------- WELCOME ----------------------------')
time.sleep(3)
print('\nCleaning .................')

def generate_hash(self, Filename:str)->str:
Filehash = sha256()
try:
with open(Filename, 'rb') as File:
fileblock = File.read(self.block_size)
while len(fileblock)>0:
Filehash.update(fileblock)
fileblock = File.read(self.block_size)
Filehash = Filehash.hexdigest()
return Filehash
except:
return False

def clean(self)->None:
all_dirs = [path[0] for path in os.walk('.')]
for path in all_dirs:
os.chdir(path)
All_Files =[file for file in os.listdir() if os.path.isfile(file)]
for file in All_Files:
filehash = self.generate_hash(file)
if not filehash in self.File_hashes:
if filehash:
self.File_hashes.append(filehash)
#print(file)
else:
byte_saved = os.path.getsize(file); self.count_cleaned+=1
self.Total_bytes_saved+=byte_saved
os.remove(file); filename = file.split('/')[-1]
print(filename, '.. cleaned ')
os.chdir(self.home_dir)

def cleaning_summary(self)->None:
mb_saved = self.Total_bytes_saved/1048576
mb_saved = round(mb_saved, 2)
print('\n\n--------------FINISHED CLEANING ------------')
print('File cleaned : ', self.count_cleaned)
print('Total Space saved : ', mb_saved, 'MB')
print('-----------------------------------------------')

def main(self)->None:
self.welcome();self.clean();self.cleaning_summary()

if __name__ == '__main__':
App = Duplython()
App.main()

Ứng dụng Xoá các File trùng lặp bằng Python của chúng ta đã hoàn tất, bây giờ để chạy ứng dụng, hãy chạy nó trong thư mục cụ thể mà bạn muốn dọn dẹp và nó sẽ đệ quy qua một thư mục nhất định để tìm tất cả các File và xóa File trùng lặp.

Kết quả

$ python3 app.py
******************************************************************
**************** DUPLYTHON ****************************
********************************************************************
​
​
---------------- WELCOME ----------------------------
​
Cleaning .................
0(copy).jpeg .. cleaned
0 (1)(copy).jpeg .. cleaned
0 (2)(copy).jpeg .. cleaned

​
--------------FINISHED CLEANING ------------
File cleaned : 3
Total Space saved : 0.38 MB

Sử dụng flat state trong Vue Store

Sử dụng flat state trong Vue Store

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

Đầu tiên chúng ta cần trả lời câu hỏi global state có phải là phương thuốc chữa bá bệnh cho các vấn đề liên quan tới state? Mình chỉ đưa dữ liệu vào Vuex store như là lựa chọn cuối cùng và có một lý do cụ thế để phải sử dụng. Điều thứ 2, luôn giữ global state ở dạng cây một cấp, nghĩa là chúng ta không lồng dữ liệu liệu vào nhau như bên dưới

  3 phút làm quen với Vue.js
  Autosaving cùng Vuex

Đọc thêm https://markus.oberlehner.net/blog/should-i-store-this-data-in-vuex/ để có khái niệm khi nào cần dữ liệu trong store và khi nào không.

Quan điểm về flat state (không lưu dữ liệu lồng nhau trong store) được lấy cảm hứng từ chú Matt Biilmann chia sẽ về quan điểm về Redux sau khi làm cái dashboard cho Netlify trong bài phỏng vấn Architecting the Netlify Dashboard with React and Redux

cap_1: {
    cap_2: {
        cap_3: {
        }
    }
}

Rất khó để sync dữ liệu ở dạng lồng ghép như vậy.

Ví dụ, có danh sách bài viết, mỗi bài viết được nhét thông tin tác giả bên trong, có nhiều bài viết có cùng một tác giả, rồi ngày đẹp trời tác giả này đổi tên, thì chúng ta phải đi sync lại toàn bộ tất cả bài viết của ổng.

const articles = [
  // bài viết này được load trước
  {
    author: {
      avatar: 'https://picsum.photos/id/1011/25',
      id: 1,
      name: 'Jane Doe',
    },
    id: 1,
    intro: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr.',
    title: 'Lorem Ipsum',
  },
  // tác giả đó ổng vô đổi avatar,
  // rồi chúng ta load thêm bài viết
  // avatar của ổng đã không còn như xưa
  {
    author: {
      avatar: 'https://picsum.photos/id/2000/25',
      id: 1,
      name: 'Jane Doe',
    },
    id: 2,
    intro: 'Stet clita kasd gubergren, no sea takimata sanctus est.',
    title: 'Dolor sit',
  },
];

Cách mà chúng ta nên lưu, tách riêng 2 thằng

const articles = {
  1: {
    author: 1,
    id: 1,
    intro: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr.',
    title: 'Lorem Ipsum',
  },
  2: {
    author: 1,
    id: 2,
    intro: 'Stet clita kasd gubergren, no sea takimata sanctus est.',
    title: 'Dolor sit',
  },
};

const authors = {
  1: {
    avatar: 'https://picsum.photos/id/2000/25',
    id: 1,
    name: 'Jane Doe',
  },
};

Những kiểu thực thể khác nhau, chúng ta tách ra thành các module riêng biệt, dùng khái niệm foreign key (khóa ngoại) như trong database

// src/store/modules/article.js
import Vue from 'vue';

import { normalizeRelations, resolveRelations } from '../helpers';
import articleService from '../../services/article';

const state = {
  byId: {},
  allIds: [],
};

const getters = {
  // trả về một article với giá trị id được truyền vào
  find: (state, _, __, rootGetters) => id => {
    // dùng ID để lấy thông tin tác giả
    return resolveRelations(state.byId[id], ['author'], rootGetters);
  },
  // trả về danh sách articles
  list: (state, getters) => {
    return state.allIds.map(id => getters.find(id));
  },
};

const actions = {
  load: async ({ commit }) => {
    const articles = await articleService.list();
    articles.forEach((item) => {
      commit('add', normalizeRelations(item, ['author']));
      // thêm hoặc update order
      commit('author/add', item.author, {
        root: true,
      });
    });
  },
};

const mutations = {
  add: (state, item) => {
    Vue.set(state.byId, item.id, item);
    if (state.allIds.includes(item.id)) return;
    state.allIds.push(item.id);
  },
};

export default {
  actions,
  getters,
  mutations,
  namespaced: true,
  state,
};
// src/store/helpers.js
export function normalizeRelations(data, fields) {
  return {
    ...data,
    ...fields.reduce((prev, field) => ({
      ...prev,
      [field]: Array.isArray(data[field])
        ? data[field].map(x => x.id)
        : data[field].id,
    }), {}),
  };
}

export function resolveRelations(data, fields, rootGetters) {
  return {
    ...data,
    ...fields.reduce((prev, field) => ({
      ...prev,
      [field]: Array.isArray(data[field])
        ? data[field].map(x => rootGetters[`${field}/find`](x))
        : rootGetters[`${field}/find`](data[field]),
    }), {}),
  };
}

Sử dụng

<template>
  <div id="app">
    <ArticleList :articles="articles"/>
  </div>
</template>

<script>
// src/App.vue
import { mapActions, mapGetters } from 'vuex';

import ArticleList from './components/ArticleList';

export default {
  name: 'App',
  components: {
    ArticleList,
  },
  computed: {
    ...mapGetters('article', { articles: 'list' }),
  },
  created() {
    this.loadArticles();
  },
  methods: {
    ...mapActions('article', { loadArticles: 'load' }),
  },
};
</script>

Trong component App.vue chúng ta lấy các getter và action trong article module, khi vừa khởi tạo component, gọi action loadArticle để lấy dữ liệu

<template>
  <ul class="ArticleList">
    <li
      v-for="article in articles"
      :key="article.id"
    >
      <h2>{{ article.title }}</h2>
      <p>{{ article.intro }}</p>
      <div class="ArticleList__author">
        <img class="ArticleList__avatar" :src="article.author.avatar" :alt="article.author.name">
        {{ article.author.name }}
      </div>
    </li>
  </ul>
</template>

<script>
export default {
  name: 'ArticleList',
  props: {
    articles: {
      required: true,
      type: Array,
    },
  },
};
</script>

Nhờ vào các hàm getter và resolveRelations(), chúng ta có thể dễ dàng truy cập author của từng article

📜 Make your Vuex State Flat: State Normalization with Vuex

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

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

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

Software Developer và 5 bài học kinh nghiệm quan trọng

5 bài học kinh nghiệm quan trọng được đúc kết bởi một Software Developer

Dịch từ bài viết của tác giả Stephen McLean

Với 4 năm làm việc ở vị trí Software Developer tôi đã rút ra được nhiều bài học lớn cho bản thân và hy vọng bài viết này sẽ giúp các dev học hỏi thêm những điều mình chưa biết.

  10 Công cụ Go-To Tech dành riêng cho các Software Developer
  Biến Git và GitHub trở thành công cụ đắc lực cho Software Engineer

Những bài học kinh nghiệm của Software Developer

1. Đừng cho rằng mọi thứ luôn hoạt động trơn tru

Ở job đầu tiên của mình sau khi ra trường, tôi được giao một task nhỏ trong chuỗi dự án dài hạn. Dự án này có sự tham gia của rất nhiều dev và phải chạy nước rút nhiều lần để hoàn thành. Nó có lượng codebase cực kỳ lớn, phức tạp và tích hợp với nhiều dịch vụ outsource.

Xem thêm Thị trường Outsourcing Vietnam 2019 – Thiên đường Outsourcing mới của thế giới

Công việc của tôi là fix một số unit tests không thể chạy liên tục, code của unit tests này tương đối cũ và được viết bởi một Senior Developer. Vì chúng hoạt động tốt trên UI và đã thông qua bài kiểm tra QA nên tôi nghĩ rằng sai sót có thể nằm ở kỹ năng kiểm thử của mình.

topdev

Tôi dành gần 3 ngày để fix những tests không có vấn đề gì như thế nên thời gian lâu hơn. Khi trình bày với sếp, anh ấy nói với tôi rằng đừng bao giờ cho rằng code của người khác thì luôn đúng. Lời khuyên này dường như không chỉ đúng với việc viết code:

  • Đừng nghĩ rằng khi bạn giao việc gì thì người thực hiện đều làm đúng theo như vậy mà thay vào đó, hãy có một thỏa thuận rõ ràng và theo dõi kỹ càng các task đã giao để đạt được kết quả tốt.
  • Đừng cho rằng đối phương đã hiểu những gì bạn nói kể cả khi họ nói đã hiểu và có thể làm được. Tôi rút ra bài học này sau khi là mentor của nhiều Junior Developer. Để chắc chắn bạn nên yêu cầu họ trình bày lại những gì bạn đã hướng dẫn theo cách họ hiểu.
  • Đừng nghĩ rằng đối phương luôn sai. Nhiều người quá tin tưởng vào code của mình và đổ lỗi cho người khác khi code không chạy được. Bạn sẽ được đánh giá cao hơn nếu biết nhìn nhận và test lại code của mình để đảm bảo sự chính xác hơn là chỉ chối lỗi.

Xem thêm Junior developer là gì? Những quy tắc bất biến dành cho Junior developer

2. Hãy suy nghĩ trước khi code

Sự thật là đa phần các dev đều thích automation, họ luôn tìm cách tự động hóa mọi thứ để cải thiện vấn đề. Tuy nhiên, đừng vội vàng viết code để làm điều đó, nhất là khi coding để sửa lỗi sai. Hãy nghiên cứu kỹ nguyên nhân vấn đề chứ đừng vội vàng tìm giải pháp. Trao đổi với nhiều người khác nhau không chỉ các dev để xem đây là lỗi kỹ thuật hay do quy trình, sau đấy hãy tìm giải pháp thực hiện. Vì nếu không hiểu được ngọn nguồn vấn đề, các dev và team của mình sẽ tiếp tục phạm phải nhiều sai lầm hơn khi làm việc mà thôi. 

Tham khảo tuyển dụng software engineer lương cao trên TopDev

3. Kết quả quan trọng hơn cách tạo ra kết quả

Sau 4 năm là Software Developer tôi nhận ra rằng, tools được sử dụng để xây dựng phần mềm là gì không quan trọng, miễn là nó có thể giúp tôi hoàn thành tốt nhiệm vụ là được. Khách hàng cũng chỉ quan tâm đến sản phẩm cuối cùng và hoạt động của nó có hiệu quả hay không, họ không để ý đến việc làm sao để nó hoạt động được như vậy.

topdev

4. Những vấn đề không do lỗi kỹ thuật mới là vấn đề khó giải quyết nhất

Khi ở giảng đường, mọi sai sót đều do kỹ thuật và bạn dễ dàng tìm được cách để đoạn code mình viết chạy được. Nhưng trong công việc thì không đơn giản như vậy. Bạn sẽ gặp rất nhiều chuyện phát sinh khi chạy một dự án: Làm sao để đảm bảo sự kết nối giữa các bên liên quan với nhau tốt nhất dù khác múi giờ làm việc, làm sao đảm bảo quy trình hoạt động và document được lưu trữ đầy đủ, giúp đỡ các dev mới trong team, giới thiệu cách hoạt động dự án cho khách hàng một cách dễ hiểu nhất,… Đó chỉ là một trong rất nhiều các vấn đề bạn phải giải quyết khi là Software Developer.

  Liệu Software Engineer có phải là nghề dễ ăn?
  20 trường hợp sử dụng lệnh Docker cho developer

5. Mọi vai trò trong team đều quan trọng như nhau

Một dự án sẽ không thể diễn ra suôn sẻ nếu không có sự kết hợp giữa các team liên quan và mỗi thành viên trong một team với nhau. Mỗi người sẽ đóng một vai trò nhất định từ BA, QA, quản lý dự án, quản lý các bên liên quan khác đến các dev. Code sẽ vô nghĩa nếu không có các stakeholder cùng nhau xây dựng dự án.

Kết luận

Hy vọng rằng những chia sẻ trong bài viết này có thể giúp bạn có thêm kinh nghiệm để hoạt động hiệu quả hơn với tư cách là một Software Developer.

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

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

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

QUnit — Những bước chân TDD đầu tiên trên JavaScript

QUnit — Những bước chân TDD đầu tiên trên JavaScript

Bài viết được sự cho phép của BBT Tạp chí Lập trình

TDD là gì?

TDD (Test Driven Development) là một phương thức làm việc, hay một quy trình viết mã hiện đại. Lập trình viên sẽ thực hiện thông qua các bước nhỏ (BabyStep) và tiến độ được đảm bảo liên tục bằng cách viết và chạy các bài test tự động (automated tests). Quá trình lập trình trong TDD cực kỳ chú trọng vào các bước liên tục sau:

  1. Viết 1 test case cho hàm mới. Đảm bảo rằng test sẽ fail.
  2. Chuyển qua viết code sơ khai nhất cho hàm đó để test có thể pass.
  3. Tối ưu hóa đoạn code của hàm vừa viết sao cho đảm bảo test vẫn pass và tối ưu nhất cho việc lập trình kế tiếp
  4. Lặp lại cho các hàm khác từ bước 1

Phát triển hướng kiểm thử TDD (Test-Driven Development) là một phương pháp phát triển phần mềm trong đó kết hợp phương pháp Phát triển kiểm thử trước (Test First Development) và điều chỉnh lại mã nguồn (Refactoring).

Mục tiêu quan trọng nhất của TDD là hãy nghĩ về kết qủa của bạn trước khi viết mã nguồn cho chức năng. Nhìn chung, mục tiêu của TDD là viết mã nguồn sáng sủa, rõ ràng và hạn chế lỗi, dễ dàng mở rộng.

Xem việc làm javascript đãi ngộ tốt trên TopDev

QUnit là gì?

QUnit là một framework mạnh, miễn phí và dễ sử dụng để triển khai Kiểm thử Đơn vị (Unit Testing) trong JavaScript. Framework này đã được dùng cho các dự án jQuery, jQuery UI và jQuery Mobile cũng như có thể dùng cho tất cả các mã nguồn JavaScript nói chung.

Cài đặt QUnit

QUnit là một thư viện độc lập, chỉ cần một tệp JavaScript (qunit.js) và một tệp CSS (qunit.css). Bạn có thể tải chúng xuống từ trang QUnit hoặc sao chép chúng từ kho lưu trữ QUnit GitHub, như sau:

 git clone git://github.com/jquery/qunit.git

Hoặc đơn giản hơn, chúng ta có thể nhúng CDN của QUnit vào trang HTML của chúng ta:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>QUnit Example</title>
    <link rel="stylesheet" href="https://code.jquery.com/qunit/qunit-2.10.0.css">
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<script src="https://code.jquery.com/qunit/qunit-2.10.0.js"></script>
<script src="tests.js"></script>
</body>
</html>

Sau đó, chúng ta tạo 1 file js là “tests.js” và viết những dòng test case đầu tiên vào đó:

QUnit.test( "hello test", function( assert ) {
    assert.ok( 1 == "1", "Passed!" );
});

Cuối cùng, hãy chạy thử file HTML của bạn và xem kết quả nhé:

QUnit — Những bước chân TDD đầu tiên trên JavaScript

Yeah, bạn đã chạy thành công 1 test case đơn giản đầu tiên, bây giờ hãy thử nâng cấp 1 chút, viết test cho 1 hàm của bạn nhé. Bạn tạo file “app.js” chứa các hàm mà bạn muốn test, và tạo sẵn vào đó hàm sayHello() như sau:

 function sayHello(yourName) {    return yourName; }

Tiếp đó, Viết một test case trong file tests.js dành cho hàm sayHello()

Qunit.test( "test sayHello", function(assert) {
  let expected = "Hello World";
  let result =  sayHello("World");
  assert.ok(expected == result,"Passed!");
});

Chạy thử HTML của bạn sẽ có kết quả như sau:

QUnit — Những bước chân TDD đầu tiên trên JavaScript

Vậy là bạn đã thành công với bước đầu có được test case “fail” với QUnit, công việc của bạn là hoàn chỉnh hàm sayHello() để “pass” được cái test này.

 function sayHello(yourName) {    return "Hello " + yourName; }

Xong rồi chạy lại trang HTML của bạn, nếu hiển thị như này:

Xanh tức là bạn đã “pass” trường hợp đó rồi. Nếu báo đỏ thì bạn hãy kiểm tra lại hàm sayHello() xem có vấn đề gì không nhé. Sau khi pass rồi thì chúng ta viết tiếp những test case mới.

Đến đây tôi đã hoàn tất việc giới thiệu với các bạn về QUnit và một hướng dẫn nho nhỏ để bạn có thể bắt đầu làm Unit Test hay xa hơn nữa là TDD với JavaScript. Bạn có thể tìm hiểu sâu hơn về QUnit tại trang web http://qunitjs.com.

Chúc bạn thành công và có những mã nguồn JavaScript chất lượng!

Author: Dư Thanh Hoàng

Bài viết gốc được đăng tải tại Tạp chí Lập trình

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

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

Một số tool hữu ích dành cho Web Developer có thể bạn chưa biết (Phần 1)

tool cho web developer

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

Ngày nay lĩnh vực công nghệ phát triển một cách vượt bậc, bên cạnh đó sự trải nghiệm người dùng cũng được theo đó mà tăng lên đáng kể. Đằng sau những giao diện bắt mắt là những ý tưởng mới mẻ, tốn rất nhiều công sức của Developer. Dưới đây mình tổng hợp một số công cụ hữu ích cho một Frontend developer/Designer được chọn lọc qua nhiều nguồn khác nhau.

Font

Trong một layout website thường sẽ có những Icon giúp website đẹp và thân thiện hơn, ngoài ra còn có tác dụng điều hướng người dùng. Trước đây để tạo các Icon đó ta phải thực hiện cắt chúng ra từ file PSD và dùng CSS để gán background hoặc dùng thẻ img để đưa Icon đó vào. Tuy nhiên hiện nay chúng ta đã có giải pháp khác đó là sử dụng Symboy Font (font chữ kiểu ký hiệu). Hiện nay có nhiều thư viện Symboy Font nhưng mạnh nhất và hay sử dụng nhất là Font Awesome, Material icon… vì nó đơn giản và dễ sử dụng.

1. Awesome Font

Font Awesome là một trong những icon font phổ biến nhất hiện nay. Với phiên bản mới nhất hiện tại 5.5.0, Font Awesome hỗ trợ trên 1400 icon free.

Một số tool hữu ích dành cho Web Developer có thể bạn chưa biết (Phần 1)

2. IcoMoon Font

IcoMoon thực chất là một ứng dụng cho phép bạn tuỳ chỉnh icon font, import SVG để tạo ra font riêng, convert font sang SVG, PDF, XAML, CSH… Và IcoMoon cung cấp hơn 5000 icon free bằng cách tối ưu từ nhiều thư viện miễn phí khác nhau

Một số tool hữu ích dành cho Web Developer có thể bạn chưa biết (Phần 1)

CSS Generator

1. CSS tool

Một số tool hữu ích dành cho Web Developer có thể bạn chưa biết (Phần 1)

Đây là công cụ tổng hợp không thể thiếu của một CSS Developer. Có rất nhiều tool dùng để tạo box-shadow, background gradient, text effect, transform…

2. Image Sprites

Với một Frontend developer chắc không xa lạ với kỹ thuật image sprites. Đây là phương pháp giúp tối ưu website, tuy nhiên để xác định tọa độ (background-position) thật là một điều khó khăn. Sau đây làm một công cụ tuyệt vời để giải quyết vấn đề trên với thao tác đơn giản.

Một số tool hữu ích dành cho Web Developer có thể bạn chưa biết (Phần 1)

Tổng kết

Trên đây là một số công cụ cần thiết của một Frontend/Design developer. Hy vọng những công cụ này có thể hỗ trợ phần nào cho công việc lên ý tưởng, hoàn thiện thiết kế UI và phát triển phần code Frontend cho các dự án của các bạn.

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

  Một số tool hữu ích dành cho Web Developer có thể bạn đã biết (Phần 2)

Xem thêm vị trí tuyển dụng web Developer hấp dẫn tại TopDev

Senior là gì? Phân biệt Senior và Junior thật chi tiết

senior là gì
senior là gì

Thị trường tuyển dụng đang phát triển, có rất nhiều thuật ngữ ra đời. Thuật ngữ Senior là một trong số đó. Vậy Senior là gì? Senior không chỉ đơn giản là một người có nhiều năm kinh nghiệm hơn, mà còn là một người đã đạt được một trình độ chuyên môn cao, có khả năng dẫn dắt đội nhóm và đưa ra các quyết định quan trọng. Bài viết này sẽ đi sâu vào khái niệm Senior là gì, những kỹ năng cần có để trở thành một Senior thực thụ, và làm thế nào để liên tục nâng cao trình độ của mình.

Senior là gì?

Senior là thuật ngữ chỉ một người đã có nhiều năm kinh nghiệm (thường là từ 3 năm trở lên), có sự hiểu biết và trải nghiệm dày dặn trong lĩnh vực của mình. Khả năng chuyên môn của họ đã được nâng cao thông qua các thách thức từ những giai đoạn Intern, Fresher, Junior trước đó.

Senior có khả năng làm việc độc lập và đảm nhận các nhiệm vụ phức tạp mà không cần sự giám sát liên tục. Senior không chỉ có kiến thức chuyên môn sâu rộng mà còn có kỹ năng quản lý thời gian, làm việc nhóm và ra quyết định dựa trên kinh nghiệm thực tế.

Senior là gì?
senior là gì

Nhiều người thường nghĩ rằng một Senior sẽ được tôi luyện từ 4 đến 5 năm. Tuy nhiên, đó là cách nghĩ sai lầm. Bạn khó có thể trở thành “tiền bối” nếu chỉ đơn thuần đảm nhận các công việc lặt vặt, dự án với quy mô nhỏ. Không có sự rèn luyện, tiếp thu cái mới về năng lực – kỹ năng, tư duy nghề nghiệp thì bạn phải chấp nhận một sự thật rằng: Bạn vẫn không khác Junior là bao.

Điều đó cho thấy việc tự tích lũy kiến thức theo quá trình mới thật sự quan trọng. Do vậy, không thể đánh giá, phân loại Senior chỉ dựa vào số năm kinh nghiệm. Và tùy thuộc vào từng loại hình công ty, việc phân chia cấp bậc Senior lại có những tiêu chí khác nhau.

Vai trò và công việc của Senior

Trong một tổ chức, vai trò của Senior rất quan trọng. Họ thường là những người dẫn dắt dự án, định hướng kỹ thuật, và đôi khi còn đóng vai trò cố vấn cho các thành viên trẻ hơn trong nhóm. Senior không chỉ đảm bảo rằng công việc được hoàn thành đúng hạn và đạt chất lượng cao mà còn đóng góp vào việc xây dựng văn hóa làm việc tích cực và hiệu quả.

Senior cũng thường là người chịu trách nhiệm trong việc đưa ra các quyết định kỹ thuật quan trọng, đảm bảo rằng các dự án phát triển theo đúng hướng và đáp ứng các yêu cầu kinh doanh. Họ cũng có trách nhiệm đào tạo và hướng dẫn những thành viên mới, giúp họ nhanh chóng nắm bắt công việc và hòa nhập với đội ngũ.

Ngoài ra, Senior cần cung cấp các báo cáo tiến độ thường xuyên cho cấp trên hoặc khách hàng, đảm bảo rằng mọi người đều cập nhật về tình trạng hiện tại của dự án. Đánh giá hiệu suất làm việc của bản thân và các thành viên trong nhóm, đưa ra các phản hồi và đề xuất cải tiến khi cần thiết.

>> Xem thêm: Senior developer là gì? Vai trò và kĩ năng cần có

Những kỹ năng giúp Senior lên “trình” hiệu quả

Kỹ năng về chuyên môn

Kỹ năng chuyên môn phản ánh sự am hiểu các kiến thức nền tảng cần phải có trước khi bạn bước vào giai đoạn phát triển năng lực

Nâng cao không ngừng kiến thức chuyên môn

Một trong những yếu tố quan trọng nhất để một Senior có thể nâng cao trình độ là không ngừng trau dồi và cập nhật kiến thức chuyên môn của mình. Ở cấp độ Senior, bạn cần có sự hiểu biết sâu rộng về lĩnh vực mà mình đang làm việc, từ các công cụ, framework đến các xu hướng công nghệ mới nhất. Việc cập nhật kiến thức liên tục giúp bạn không chỉ giữ vững vị thế mà còn trở thành người dẫn đầu trong việc áp dụng các giải pháp công nghệ tiên tiến.

Để phát triển kỹ năng chuyên môn, bạn có thể:

  • Tham gia các khóa học nâng cao, hội thảo và seminar liên quan đến lĩnh vực của mình.
  • Tham gia vào các cộng đồng chuyên môn để trao đổi và học hỏi từ các chuyên gia khác.
  • Đọc sách chuyên ngành, bài viết và nghiên cứu để nắm bắt các xu hướng mới.

Khả năng phân tích và giải quyết vấn đề

Một Senior không chỉ cần biết cách làm việc mà còn phải hiểu rõ lý do và nguyên nhân sâu xa của các vấn đề trong công việc. Kỹ năng phân tích và giải quyết vấn đề là rất cần thiết, đặc biệt trong những tình huống phức tạp, yêu cầu tư duy logic và sự sáng tạo để tìm ra giải pháp hiệu quả.

Để cải thiện kỹ năng này, bạn có thể:

  • Thực hành phân tích các vấn đề thực tế và đề xuất giải pháp.
  • Thảo luận với đồng nghiệp hoặc nhóm để lắng nghe các góc nhìn khác nhau và tìm ra phương pháp tốt nhất.
  • Tham gia các dự án thử thách để rèn luyện khả năng xử lý tình huống phức tạp.

Kỹ năng làm việc nhóm

Kỹ năng làm việc nhóm là một trong những kỹ năng cốt lõi mà mọi Senior cần phải nắm vững. Ở vị trí này, bạn không chỉ làm việc cá nhân mà còn phối hợp với các thành viên khác trong nhóm để đạt được mục tiêu chung. Hiểu rõ vai trò của mình và của các thành viên khác trong nhóm giúp bạn phối hợp hiệu quả hơn, đảm bảo rằng mọi người đều đóng góp tối đa vào thành công của dự án.

Một Senior thường được kỳ vọng có thể dẫn dắt nhóm, đặc biệt trong các dự án lớn hoặc khi đối mặt với những thách thức khó khăn. Khả năng lãnh đạo không chỉ bao gồm việc đưa ra chỉ đạo mà còn là khả năng truyền cảm hứng, thúc đẩy tinh thần đồng đội và tạo ra một môi trường làm việc tích cực.

Để phát triển kỹ năng lãnh đạo nhóm:

  • Hãy thể hiện tinh thần trách nhiệm và cam kết với công việc của nhóm.
  • Lắng nghe và hỗ trợ các thành viên trong nhóm khi họ gặp khó khăn.
  • Đưa ra các giải pháp và hướng dẫn rõ ràng để nhóm có thể thực hiện công việc một cách hiệu quả.

Làm việc Client

Làm việc với Client/User là một kỹ năng quan trọng đối với một Senior, đặc biệt trong các lĩnh vực yêu cầu sự tương tác trực tiếp với khách hàng như công nghệ thông tin, thiết kế, hay marketing. Hiểu rõ nhu cầu và mong muốn của khách hàng giúp bạn đưa ra các giải pháp phù hợp và đáp ứng được kỳ vọng của họ.

Quản lý kỳ vọng của khách hàng là một trong những thách thức lớn mà mọi Senior đều phải đối mặt. Việc này không chỉ đòi hỏi khả năng giao tiếp tốt mà còn yêu cầu sự nhạy bén trong việc xử lý các tình huống khó khăn, chẳng hạn như khi có sự khác biệt giữa mong đợi của khách hàng và khả năng thực hiện của đội ngũ.

Chuẩn bị các phương án dự phòng và kế hoạch rõ ràng để giải quyết khi có tình huống phát sinh.

Kỹ năng đàm phán

Một Senior không chỉ cần giao tiếp mà còn phải biết đàm phán và thuyết phục, đặc biệt trong các tình huống cần thương lượng về ngân sách, thời gian hoàn thành, hoặc các yêu cầu kỹ thuật. Kỹ năng này giúp bạn đạt được các thỏa thuận có lợi và duy trì mối quan hệ tốt đẹp với các bên liên quan.

Để cải thiện kỹ năng đàm phán:

  • Hãy chuẩn bị kỹ lưỡng trước mỗi cuộc đàm phán, nắm vững thông tin và dữ liệu cần thiết.
  • Hiểu rõ lợi ích của cả hai bên và tìm kiếm giải pháp win-win.
  • Giữ thái độ linh hoạt và sẵn sàng thương lượng để đạt được mục tiêu chung.

So sánh Senior và Junior

Dưới đây là bảng so sánh giữa Senior và Junior để giúp bạn dễ dàng so sánh các yếu tố quan trọng:

Tiêu Chí Junior Senior
Kinh Nghiệm Ít kinh nghiệm hoặc mới bắt đầu sự nghiệp Nhiều năm kinh nghiệm (thường từ 5-10 năm trở lên)
Kiến Thức Chuyên Môn Đang học hỏi và phát triển kỹ năng cơ bản Kiến thức chuyên môn sâu rộng, cập nhật liên tục
Giải Quyết Vấn Đề Cần sự hướng dẫn khi gặp vấn đề Có khả năng phân tích và giải quyết vấn đề phức tạp
Mức Độ Độc Lập Cần sự giám sát và hỗ trợ từ cấp trên Làm việc độc lập mà không cần sự giám sát liên tục
Vai Trò Trong Nhóm Hỗ trợ và thực hiện các nhiệm vụ dưới sự hướng dẫn Lãnh đạo nhóm, đào tạo Junior, chịu trách nhiệm dự án
Giao Tiếp Đang phát triển kỹ năng giao tiếp Giao tiếp hiệu quả, có khả năng thuyết phục và đàm phán
Lãnh Đạo Chủ yếu là người thực hiện nhiệm vụ Định hướng, lãnh đạo và truyền cảm hứng cho đội nhóm
Đóng Góp Vào Tổ Chức Đóng góp ở mức độ công việc cá nhân Tham gia vào chiến lược, cải tiến quy trình, nâng cao hiệu quả tổ chức
Mức thu nhập Mức lương trung bình cho Junior thường từ 8-15 triệu VND/tháng tại Việt Nam. Mức lương trung bình cho Senior có thể từ 25-50 triệu VND/tháng, hoặc hơn tùy vào ngành nghề và công ty.

Khi bạn đang làm việc với chức danh Junior nhưng cảm thấy mình đã đạt được trình độ của Senior, đừng ngần ngại apply vào vị trí Senior bạn nhé, đây chính là thử thách đầu tiên trên con đường phát triển của bạn.

Việc trở thành Senior không phải là điểm dừng mà là một bước tiến mới, đòi hỏi sự tiếp tục học hỏi và phát triển để duy trì và nâng cao năng lực chuyên môn.

>> Xem thêm: So sánh chi tiết Fresher, Junior và Senior

Lời kết

Senior là vị trí đòi hỏi nhiều kỹ năng khác nhau tương ứng với từng ngành nghề nhất định. Hãy đầu tư nhiều vào sự trải nghiệm thay vì mãi loay hoay một nhiệm vụ. Sự đào thải và tính cạnh tranh luôn tồn tại trong môi trường làm việc của các Senior. Đừng để bản thân rơi vào áp lực! Không ngừng nỗ lực, nâng cao trình độ chuyên môn là điều các Senior cần ghi nhớ. TopDev hy vọng, bài viết đã có những chia sẻ bổ ích giúp các bạn có cái nhìn rõ hơn về senior là gì; các kỹ năng cần thiết của một Senior. Chúc các bạn có sự chuẩn bị tốt nhất cho mục tiêu của chính mình.

Tuyển dụng lập trình viên đãi ngộ tốt, tham khảo ngay

Một số đoạn code Python phổ biến bạn nên thuộc lòng

Một số đoạn code Python phổ biến bạn nên thuộc lòng

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

Đảo ngược chuỗi trong Python

Đoạn mã sau đảo ngược một chuỗi bằng cách sử dụng thao tác cắt (slicing) trong Python.

# Đảo ngược chuỗi sử dụng slicing

my_string = "ABCDE"
reversed_string = my_string[::-1]

print(reversed_string)

# Kết quả
# EDCBA

Viết Hoa ký tự đầu tiên của mỗi từ

Đoạn code sau có thể được sử dụng để chuyển đổi một chuỗi thành trường chuỗi mới được viết HOA ký tự đầu tiên của mỗi từ.

Điều này được thực hiện bằng cách sử dụng phương thức title() của string class.

my_string = "đây là một chuỗi"

# Sử dụng hàm title() của lớp string
new_string = my_string.title()

print(new_string)

# kết quả
# Đây Là Một Chuỗi

Tìm việc python các công ty tập đoàn

Tìm các phần tử duy nhất trong một chuỗi

Đoạn code sau có thể được sử dụng để tìm tất cả các phần tử duy nhất trong một chuỗi.

Chúng ta sử dụng tính chất của kiểu dữ liệu set: Tất cả các phần tử trong set là duy nhất.

my_string = "aavvccccddddeee"

# Chuyển chuỗi thành một set
temp_set = set(my_string)

# Chuyển set thành một chuỗi sử dụng join
new_string = ''.join(temp_set)

print(new_string)

# Kết quả
# acdve

# Vì set không có thứ tự
# nên thứ tự chuỗi mới nhận được là ngẫu nhiên

In một Chuỗi hoặc một List n lần

Bạn có thể sử dụng phép nhân (*) với chuỗi hoặc List. Điều này cho phép chúng ta nhân chúng bao nhiêu lần tùy thích.

n = 3 # Số lần lặp lại

my_string = "abcd"
my_list = [1,2,3]

print(my_string*n)
# abcdabcdabcd

print(my_list*n)
# [1,2,3,1,2,3,1,2,3]

Một trường hợp sử dụng thú vị của điều này có thể là để xác định một list với các giá trị không đổi – hãy thử xem:

n = 4
my_list = [0]*n # n Độ dài của list
# [0, 0, 0, 0]
  Quy tắc đặt tên biến trong Python đúng chuẩn 2024

List comprehension

List comprehension cung cấp cho chúng ta một cách đơn giản, thanh lịch để tạo list dựa trên các list khác.

Đoạn code sau tạo một list mới bằng cách nhân từng phần tử của list cũ với 2.

# Nhân mỗi phần tử của list với 2

original_list = [1,2,3,4]

new_list = [2*x for x in original_list]

print(new_list)
# [2,4,6,8]

Hoán đổi giá trị giữa hai biến trong Python

Python làm cho việc hoán đổi giá trị giữa 2 biến khá đơn giản mà không cần sử dụng một biến trung gian khác.

a = 1
b = 2

a, b = b, a

print(a) # 2
print(b) # 1

Tuyển dụng python Hà Nội lương cao, tham khảo ngay!

Tách một chuỗi thành một list

Chúng ta có thể tách một chuỗi thành một list chứa các chuỗi con bằng phương thức .split().

Bạn cũng có thể truyền một đối số (dấu phân cách) để hướng dẫn tách chuỗi theo chỉ định của bạn.

string_1 = "Tên tôi là NIIT Hà Nội"
string_2 = "chuỗi 1/ chuỗi 2"

# Tách chuỗi mặc định sẽ tách từ khoảng trắng ' '
print(string_1.split())
# ['Tên', 'tôi', 'là', 'NIIT', 'Hà', 'Nội']

# Tách chuỗi từ ký tự '/'
print(string_2.split('/'))
# ['chuỗi 1', ' chuỗi 2']

Kết hợp một danh sách các chuỗi thành một chuỗi

Ngược lại ở ví dụ trên, chúng ta có danh sách các chuỗi. Bây giờ ghép chúng lại thành một chuỗi duy nhất.

Chúng ta sẽ sử dụng phương thức join().

Trong trường hợp này, chúng ta truyền đối số (dấu phân tách) để hướng dẫn ghép chuỗi. (Mình sẽ sử dụng dấu phảy)

list_of_strings = ['Tên', 'tôi', 'là', 'NIIT', 'Hà', 'Nội']

# Sử dụng join và phân tách bằng dấu phảy
print(','.join(list_of_strings))

# Output
# Tên,tôi,là,NIIT,Hà,Nội
  Python: Cách in mà không cần dòng mới

Kiểm tra một chuỗi có phải chuỗi đối xứng

Vì chúng ta đã biết cách đảo ngược chuỗi nên việc kiểm tra một chuỗi có phải chuỗi đối xứng hay không sẽ rất đơn giản.

my_string = "abcba"

if my_string == my_string[::-1]:
    print("Chuỗi đối xứng")
else:
    print("Chuỗi không đối xứng")

# Kết quả
# Chuỗi đối xứng

Tình số lần xuất hiện của các phần tử trong một List

Có nhiều cách để làm điều này, nhưng mình thích sử dụng Counter của Python.

Bộ đếm Python theo dõi tần suất của từng phần tử trong container.

Counter() trả về một dictionary với các phần tử là key và số lần xuất hiện là value.

Chúng tôi cũng sử dụng hàm most_common() để lấy phần tử most_frequent (xuất hiện nhiều nhất) trong List.

# Tìm số lần xuất hiện của mỗi phần từ trong List

# import Counter
from collections import Counter

my_list = ['a','a','b','b','b','c','d','d','d','d','d']
count = Counter(my_list) # Xác định đối tượng counter

print(count) # In thông tin tất cả
# Counter({'d': 5, 'b': 3, 'a': 2, 'c': 1})

print(count['b']) # Số lần xuất hiện của phần tử cụ thể
# 3

print(count.most_common(1)) # Phần tử xuất hiện nhiều nhất
# [('d', 5)]

Tìm xem hai chuỗi có đảo chữ không

Một ứng dụng thú vị của Counter là tìm chuỗi đảo chữ.

Đảo chữ là một từ hoặc cụm từ được hình thành bằng cách sắp xếp lại các chữ cái của một từ hoặc cụm từ khác nhau.

Nếu các đối tượng Counter của hai chuỗi bằng nhau, thì chúng là đảo chữ cái.

# import Counter
from collections import Counter

str_1, str_2, str_3 = "acbde", "abced", "abcda"
cnt_1, cnt_2, cnt_3  = Counter(str_1), Counter(str_2), Counter(str_3)

if cnt_1 == cnt_2:
    print('1 và 2 Đảo chữ')
if cnt_1 == cnt_3:
    print('1 và 3 Đảo chữ')

Sử dụng Khối try-except-else

Xử lý lỗi trong Python có thể được thực hiện dễ dàng bằng cách sử dụng khối try / except.

Thêm một câu lệnh else vào khối này rất hữu ích. Nó sẽ chạy khi không có ngoại lệ xảy ra trong khối try.

Nếu bạn cần chạy một cái gì đó không phân biệt ngoại lệ, hãy sử dụng finaly.

a, b = 1,0

try:
    print(a/b)
    # Ngoại lệ xảy ra khi b == 0
except ZeroDivisionError:
    print("Chia cho số 0")
else:
    print("Không có ngoại lệ xảy ra")
finally:
    print("Luôn luôn chạy lệnh này!")

Việc làm python Đà Nẵng đãi ngộ tốt

Sử dụng liệt kê (Enumerate) để nhận các cặp index / value

Kịch bản sau đây sử dụng phép liệt kê (enumerate) để lặp qua các giá trị trong list cùng với các chỉ mục (index) của chúng.

my_list = ['a', 'b', 'c', 'd', 'e']

for index, value in enumerate(my_list):
    print('{0}: {1}'.format(index, value))

# 0: a
# 1: b
# 2: c
# 3: d
# 4: e

Kiểm tra mức sử dụng bộ nhớ của một đối tượng

Đoạn code sau đây có thể được sử dụng để kiểm tra mức sử dụng bộ nhớ của một đối tượng.

import sys

num = 21

print(sys.getsizeof(num))

# Kết quả trong Python 2 là: 24
# Kết quả trong Python 3 là: 28

Hợp nhất hai từ điển

Trong khi ở Python 2, chúng ta đã sử dụng phương thức update() để hợp nhất hai Dictionaries.

Nhưng Python 3.5 làm cho quá trình này đơn giản hơn nhiều.

Trong đoạn code được đưa ra dưới đây, hai Dictionaries được hợp nhất.

Lưu ý: Các value của Dictionaries thứ hai sẽ được sử dụng nếu key bị trùng với key trong Dictionaries thứ nhất.

dict_1 = {'apple': 9, 'banana': 6}
dict_2 = {'banana': 4, 'orange': 8}

combined_dict = {**dict_1, **dict_2}

print(combined_dict)
# Output
# {'apple': 9, 'banana': 4, 'orange': 8}

Nếu bạn muốn giữ các giá trị của chúng, bạn có thể làm như sau:

def mergeDict(dict1, dict2):
   ''' Hợp nhất dictionaries và giữ giá trị của key phổ biến trong list'''
   dict3 = {**dict1, **dict2}
   for key, value in dict3.items():
       if key in dict1 and key in dict2:
               dict3[key] = [value , dict1[key]]
 
   return dict3

# Hợp nhất dictionaries và thêm giá trị của key phổ biến trong list
dict3 = mergeDict(dict1, dict2)
 
print('Dictionary 3 :')
print(dict3)

Tính thời gian thực hiện để thực thi một đoạn code trong Python

Đoạn code sau sử dụng thư viện time để dễ dàng giúp chúng ta tính thời gian thực để thực thi một đoạn code trong Python.

# import thư viện time
import time

# Kiểm tra thời gian bắt đầu
start_time = time.time()

# Code cần kiểm tra
a, b = 1,2
c = a+ b

# Kiểm tra thời gian kết thúc
end_time = time.time()

# Tính thời gian chênh lệch
time_taken_in_micro = (end_time- start_time)*(10**6)

# In kết quả
print(" Thời gian thực thi micro_seconds: {0} ms").format(time_taken_in_micro)

Trải phẳng list trong list

Đôi khi bạn không chắc chắn về mức độ lồng trong list của mình và bạn chỉ muốn trải phẳng tất cả các phần tử trong đó thành một list duy nhất.

Đây là cách bạn có thể thực hiện:

from iteration_utilities import deepflatten

# Nếu bạn chỉ có một lồng 1 cấp, sử dụng cái này
def flatten(l):
  return [item for sublist in l for item in sublist]

l = [[1,2,3],[3]]
print(flatten(l))
# [1, 2, 3, 3]

# Nếu bạn không biết list lồng sâu thế nào
l = [[1,2,3],[4,[5],[6,7]],[8,[9,[10]]]]

print(list(deepflatten(l, depth=3)))
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Lấy mẫu từ một List

Đoạn mã sau tạo ra n số mẫu ngẫu nhiên từ một list nhất định bằng thư viện random.

# import thư viện
import random

my_list = ['a', 'b', 'c', 'd', 'e']
num_samples = 2

samples = random.sample(my_list,num_samples)
print(samples)

# Kết quả nhận được là ngẫu nhiên:
# [ 'a', 'e']

Bạn cũng có thể sử dụng thư viện secrets để tạo các mẫu ngẫu nhiên để mã hóa.

Đoạn code sau sẽ chỉ hoạt động trên Python 3.

import secrets                              # imports secure module.
secure_random = secrets.SystemRandom()      # Tạo một đối tượng secure ngẫu nghiên.

my_list = ['a','b','c','d','e']
num_samples = 2

samples = secure_random.sample(my_list, num_samples)

print(samples)

# Kết quả nhận được là ngẫu nhiên:
# [ 'e', 'd']

Chuyển đổi một số thành danh sách các chữ số trong Python

Đoạn code sau sẽ chuyển đổi một số nguyên thành một danh sách các chữ số.

num = 123456

# Sử dụng map
list_of_digits = list(map(int, str(num)))

print(list_of_digits)
# [1, 2, 3, 4, 5, 6]

# Sử dụng kỹ thuật list comprehension
list_of_digits = [int(x) for x in str(num)]

print(list_of_digits)
# [1, 2, 3, 4, 5, 6]

Kiểm tra tính duy nhất

Hàm trong ví dụ sau sẽ kiểm tra xem tất cả các phần tử trong list có phải là duy nhất hay không.

def unique(l):
    if len(l) == len(set(l)):
        print("Tất cả phần tử là duy nhất")
    else:
        print("List có phần tử trùng lặp")

unique([1,2,3,4])
# Tất cả phần tử là duy nhất

unique([1,1,2,3])
# List có phần tử trùng lặp

Tổng kết

Đây là một số Đoạn code Python ngắn mình thấy cực kỳ hữu ích trong công việc hàng ngày của mình.

Nếu bạn chưa hiểu lắm, Khóa học Python trên ucode.vn sẽ dạy bạn đầy đủ và chi tiết nhất để bạn hoàn toàn làm chủ Ngôn ngữ Python.

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

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

5 kỹ năng quan trọng cho ngành Nhân sự

ngành nhân sự

Ngành nhân sự ngày nay đòi hỏi nhiều kỹ năng. Đó cũng là thách thức lớn đối với những ai lựa chọn theo đuổi ngành nghề này. Khi thế giới nhân sự phát triển, việc tìm kiếm những người có kỹ năng tốt để đáp ứng sự vận hành hiện đại là ưu tiên hàng đầu. Liệu các kỹ năng nào sẽ giúp bạn có đủ cạnh tranh trong thị trường này? Cùng TopDev điểm qua những kỹ năng mà một HR cần phải.

Giao tiếp

Vấn đề giao tiếp được đánh giá là quan trọng. Vì nó được xem là chiếc chìa khóa giúp bạn thành công. Những người làm nhân sự cần có một khả năng giao tiếp tốt. 

ngành nhân sự

Không chỉ đơn thuần là trao đổi thông tin, bạn còn phải nắm bắt được cảm xúc, suy nghĩ của người tiếp nhân thông tin. Đồng thời, nhận biết những biểu hiện của giao tiếp phi ngôn ngữ: cử chỉ, hành vi,… Chằng hạn trong công tác quản trị nhân sự, mỗi lời nói của các lãnh đạo/nhà quản lý  đều thể hiện một thông điệp nào đó. Và phát ngôn đó đủ sức tạo ra sự ảnh hưởng đến nhân viên.

Tuyển dụng

Sẽ là một thiếu sót lớn nếu bỏ qua kỹ năng này. Vì thực tế, nó chính là một phần công việc mà người người thuộc lĩnh vực nhân sự cần phải thực hiện.

  Những sai lầm phổ biến trong Tuyển dụng Nhân sự

ngành nhân sự

Các thách thức trong việc tìm kiếm, thu hút ứng viên tài năng; và làm thế nào để quản trị nguồn nhân lực hiệu quả đang là mối quan tâm lớn của nhà tuyển dụng. Đó là lý do tại sao họ cần những HR giàu kinh nghiệm và kỹ năng. Điều này mở ra một cuộc chiến tuyển dụng lớn. Và nếu bạn là người có kỹ năng tốt, bạn sẽ có lợi thế nhiều hơn trong cuộc chơi tuyển dụng. 

Công nghệ nhân sự và phân tích dữ liệu

Công nghệ nhân sự là kỹ năng gia tăng các cơ hội tuyển dụng. Những lợi thế mà nó mang lại rất lớn do HR và công nghệ đang ngày càng gắn kết chặt chẽ với nhau.

Việc quản trị nguồn nhân lực đang đi vào thời đại kỹ thuật số. Ngày càng nhiều quá trình được tự động hóa và tăng cường bởi công nghệ. Vì thế, nếu có những hiểu biết cơ bản về công nghệ, bạn sẽ chạm gần hơn với sự thành công.

ngành nhân sự

Đồng thời, nhiều người nghĩ rằng phân tích dữ liệu là một kỹ năng không quá quan trọng. Và họ bỏ qua chúng, điều này thật sai lầm!

Với sự phát triển nguồn dữ liệu đa dạng, nhà tuyển dụng cần những người có khả năng đọc được dữ liệu tốt. Điều này giúp cho công tác nhân sự trở nên chặt chẽ hơn. Từ đó, việc tiếp cận và khai thác nguồn thông tin nhiều hơn.

Trí tuệ cảm xúc – EI

Trí tuệ cảm xúc là tiêu chí quan trọng để đánh giá bạn có thể trở thành một lãnh đạo nhân sự giỏi.

Đối với ngành Nhân sự, trí tuệ cảm xúc đã trở thành một chiến lược quan trọng. Tại sao? Vì nó là một trong những yếu tố quyết định liệu bạn có đủ sự phù hợp với vai trò ứng tuyển hay không. Ngoài ra, sự hiểu biết từ EI có thể giúp bạn xác định xu hướng hành vi của tổ chức/doanh nghiệp. 

  Trí tuệ cảm xúc là gì và áp dụng như thế nào trong ngành Nhân sự

ngành nhân sự

Với EI, bạn có thể khám phá cảm xúcnhững tác động đa chiều xung quanh. Đồng thời, EI còn giúp hình thành nên một môi trường làm việc thân thiện, vui vẻ. Từ đó thúc đẩy việc gia tăng hiệu suất công việc của toàn tổ chức. Chính vì điều này, bạn nên học cách nhận biết những cảm xúc. Hãy rèn luyện để bạn có thể điều khiển được tích cách, suy nghĩ và hành động của mình một cách hiệu quả.

Khả năng thích ứng và sự nhanh nhẹn

Ngành nghề nhân sự cần những ứng viên có khả năng thích nghi tốt. Đồng thời, họ phải nhanh nhẹn để đáp ứng đủ các tiêu chí.

Những nhà lãnh đạo luôn tìm kiếm những người có thể nắm bắt nhanh tình hình. Họ cũng được trao quyền khi đưa ra các đánh giá, những biện pháp, lập kế hoạch xử lý phù hợp. Điều này giúp giảm thiểu tối đa những ảnh hưởng xấu trong công tác quản trị doanh nghiệp.

ngành nhân sự

Đặc biệt, theo một khía cạnh khác các nhà quản lý nhân sự còn đòi hỏi nhân viên của họ có sự bản lĩnh. Và hơn hết, chính sự thích ứng là chiếc chìa khóa tạo ra sự bản lĩnh cho bạn. Một câu hỏi đặt ra là “Bạn sẽ tiếp tục làm công việc cũ hay bức phá khỏi“vùng an toàn?” Với những tố chất sẵn có từ ngành nhân sự cùng khả năng thích ứng tốt, bạn sẽ có những lựa chọn đúng đắn nhất.

Lời kết

Bối cảnh ngành nhân sự đang phát triển theo xu thế chung của thời đại. Vì thế, các doanh nghiệp rất cần những người đa kỹ năng đáp ứng kịp thời sự phát triển đó. Song, đó là một quá trình tích lũy và rèn luyện lâu dài. TopDev hi vọng các bạn sẽ biết đâu là điều mình cần làm. Từ đó, lập kế hoạch theo đuổi mục tiêu thông quq những hành động cụ thể nhất.


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

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

Xem thêm Top Việc làm Developer trên TopDev

Kiểm thử đơn vị trong C# với Nunit và .Net Core

Kiểm thử đơn vị trong C# với Nunit và .Net Core

Bài viết được sự cho phép của BBT Tạp chí Lập trình

Bài viết sẽ hướng dẫn từng bước xây dựng giải pháp kiểm thử đơn vị. Bài viết này đề cập tới việc kiểm thử một dự án .NET Core.

  So sánh tốc độ List collection và HashSet collection trong C#
  Namespace trong C#

Tạo dự án

Tạo một thư mục có tên là “unit-tests-using-nunit” để lưu trữ solution. Trong thư mục này, hãy chạy lệnh sau để tạo solution mới cho class library và test project:

>> dotnet new sln

Tiếp theo, tạo thư mục PrimeService. Các phác thảo sau đây cho thấy cấu trúc thư mục và tập tin:

Đi đến thư mục PrimeService và chạy lệnh sau để tạo dự án nguồn:

>> dotnet new classlib

Đổi tên Class1.cs thành PrimeService.cs. Tạo ra một triển khai fail của lớp PrimeService:

using System;
namespace Prime.Services
{
    public class PrimeService
    {
        public bool IsPrime(int candidate)
        {
            throw new NotImplementedException("Please create a test first.");
        }
    }
}

Đi đến thư mục “unit-tests-using-nunit”. Chạy lệnh sau để thêm dự án class library vào solution:

>> dotnet sln add PrimeService/PrimeService.csproj

Tạo dự án test

Tiếp theo, tạo thư mục “PrimeService.Tests”. Các phác thảo sau đây cho thấy cấu trúc thư mục:

Đi đến thư mục “PrimeService.Tests” và tạo dự án mới bằng lệnh sau:

>> dotnet new nunit

Lệnh “dotnet new” tạo ra một dự án test sử dụng NUnit làm thư viện test. Xem file cấu hình PrimeService:

using System;
namespace Prime.Services
{
    public class PrimeService
    {
        public bool IsPrime(int candidate)
        {
            throw new NotImplementedException("Please create a test first.");
        }
    }
}

Dự án test yêu cầu các gói khác để tạo và chạy kiểm thử đơn vị. Lệnh “dotnet new” trong bước trước đã thêm SDK test của Microsoft, NUnit test framework và bộ điều hợp thử nghiệm NUnit. Bây giờ, thêm class library PrimeService như một phụ thuộc khác vào dự án. Sử dụng lệnh “dotnet add reference”:

>> dotnet add reference ../PrimeService/PrimeService.csproj

Các phác thảo sau đây cho thấy cấu trúc của solution:

Thực hiện lệnh sau trong thư mục “unit-tests-using-nunit”:

>> dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj

Tạo test

Bạn viết một test fail, làm cho nó pass, sau đó lặp lại quá trình. Trong thư mục “PrimeService.Tests”, đổi tên tệp UnitTest1.cs thành PrimeService_IsPrimeShould.cs và thay thế toàn bộ nội dung của nó bằng mã sau:

using NUnit.Framework;
using Prime.Services;

namespace Prime.UnitTests.Services
{
    [TestFixture]
    public class PrimeService_IsPrimeShould
    {
        private PrimeService _primeService;

        [SetUp]
        public void SetUp()
        {
            _primeService = new PrimeService();
        }

        [Test]
        public void IsPrime_InputIs1_ReturnFalse()
        {
            var result = _primeService.IsPrime(1);

            Assert.IsFalse(result, "1 should not be prime");
        }
    }        
}

Thuộc tính [TestFixture] biểu thị một lớp có chứa các phương thức kiểm thử đơn vị. Thuộc tính [Test] chỉ ra một phương thức là một phương thức kiểm thử.

Lưu tệp này và thực hiện lệnh “dotnet test” để build các kiểm thử và class library và sau đó chạy các kiểm thử. NUnit chứa Entry Point (điểm bắt đầu của chương trình)  để chạy các kiểm thử. “dotnet test” bắt đầu trình chạy thử bằng cách sử dụng dự án kiểm thử đơn vị đã tạo.

Kiểm thử sẽ thất bại. Thực hiện kiểm thử này bằng cách viết mã đơn giản nhất trong lớp PrimeService:

public bool IsPrime(int candidate)
{
    if (candidate == 1)
    {
        return false;
    }
    throw new NotImplementedException("Please create a test first.");
}

Trong thư mục “unit-testing-using-nunit”, chạy lại lệnh “dotnet test”. Lệnh “dotnet test” build dự án PrimeService và sau đó là dự án PrimeService.Tests. Sau khi build cả hai dự án, nó chạy test này, kết quả là pass.

Thêm tính năng

Có một vài trường hợp đơn giản khác cho các số nguyên tố: 0, -1. Có thể thêm các test mới với thuộc tính [Test]. Tuy nhiên, có các thuộc tính NUnit khác cho phép viết một bộ các test tương tự.

Thuộc tính [TestCase] ​​được sử dụng để tạo một bộ các test thực thi cùng một mã nhưng có các đối số đầu vào khác nhau. Bạn có thể sử dụng thuộc tính [TestCase] ​​để chỉ định các giá trị cho các đầu vào đó.

Thay vì tạo các test mới, hãy áp dụng thuộc tính này để tạo một test theo hướng dữ liệu. Test hướng dữ liệu là phương pháp test một vài giá trị nhỏ hơn hai, là số nguyên tố thấp nhất:



public bool IsPrime(int candidate)
{
    if (candidate == 1)
    {
        return false;
    }
    throw new NotImplementedException("Please create a test first.");
}

Chạy lệnh “dotnet test” và hai trong số các test này thất bại. Để thực hiện tất cả các test, hãy thay đổi mệnh đề if ở đầu phương thức Main trong file PrimeService.cs:

public bool IsPrime(int candidate)
{
    if (candidate == 1)
    {
        return false;
    }
    throw new NotImplementedException("Please create a test first.");
}

Bài viết đã hoàn thành xây dựng một thư viện nhỏ và một bộ các kiểm thử đơn vị cho thư viện đó.

Author: Nguyễn Khánh Tùng

Bài viết gốc được đăng tải tại Tạp chí Lập trình

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

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

Các kiểu dữ liệu trong lập trình C/C++ (Data type)

Các kiểu dữ liệu trong lập trình C/C++ (Data type)

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

Kiểu dữ liệu trong C – Data type là gì?

Trong lập trình C/C++ (hoặc các ngôn ngữ khác), kiểu dữ liệu chính là phần xác định các giá trị mà một biến có thể nhận hay giá trị mà một hàm có thể trả về. Các kiểu dữ liệu này đã được lưu trữ trong chương trình C.

Dễ hiểu là, nếu xem biến là một vật và kiểu dữ liệu sẽ là vùng để chứa vật đó, thì chúng ta phải lựa chọn kiểu dữ liệu phù hợp cho biến, giống như việc lựa chọn vật đựng phù hợp để chứa vật. Ví dụ một biến cần nhập một giá trị là số nguyên thì không thể khai báo kiểu dữ liệu String được.

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

Kiểu dữ liệu của một biến, xác định kích thước (số byte) của biến đó. Có 4 kiểu dữ liệu trong lập trình C/C++ là: Kiểu dữ liệu cơ bản, kiểu dữ liệu enum, kiểu void và kiểu dữ liệu nâng cao.

Tổng hợp các kiểu dữ liệu trong C/C++

Kiểu dữ liệu cơ bản

Kiểu dữ liệu cơ bản là kiểu dữ liệu số học, có thể là số nguyên (integer) hoặc số thực (float).

Kiểu số nguyên (integer)

Với kiểu dữ liệu số nguyên (integer) ta có các loại sau:

Kiểu Kích thước Vùng giá trị
char 1 byte -128 tới 127 hoặc 0 tới 255
unsigned char 1 byte 0 tới 255
signed char 1 byte -128 tới 127
int 2 hoặc 4 bytes -32,768 tới 32,767 hoặc -2,147,483,648 tới 2,147,483,647
unsigned int 2 hoặc 4 bytes 0 tới 65,535 hoặc 0 tới 4,294,967,295
short 2 bytes -32,768 tới 32,767
unsigned short 2 bytes 0 tới 65,535
long 4 bytes -2,147,483,648 tới 2,147,483,647
unsigned long 4 bytes 0 tới 4,294,967,295

Cùng là dữ liệu kiểu số học nhưng ta lại có nhiều kiểu khác nhau. Việc này giúp tiết kiệm bộ nhớ là linh động hơn trong việc lưu dữ liệu.

Ví dụ khi lưu tuổi một người ta chỉ cần dùng kiểu char hoặc unsigned char. Vừa tiết kiệm bộ nhớ nhưng vẫn đảm bảo có thể lưu tất cả các tuổi có thể xảy ra.

Nhưng với trường hợp dữ liệu lớn hơn, như số người trong một quốc gia thì lên tới con số hàng triệu. Do đó ta phải sử dụng loại dữ liệu khác như int

Kiểu số thực (float)

Tương tự với kiểu dữ liệu số thực (dấu phẩy động) ta cũng có các loại sau:

Kiểu Kích thước Vùng giá trị Độ chính xác
float 4 byte 1.2E-38 tới 3.4E+38 6 vị trí thập phân
double 8 byte 2.3E-308 tới 1.7E+308 15 vị trí thập phân
long double 10 byte 3.4E-4932 tới 1.1E+4932 19 vị trí thập phân

Code ví dụ:

#include <stdio.h>
#include <limits.h>

int main() {
int age = 25;
int population = 85000000; // 85 triệu

printf("Age: %d - Population: %d \n", age, population);

float pi = 3.14; // giá trị số pi
printf("pi: %f \n", pi);

printf("Storage size for int : %d \n", sizeof(int)); // kích thước kiểu int
printf("Storage size for float : %d \n", sizeof(float)); // kích thước kiểu float

return 0;
}

Kết quả:

Các kiểu dữ liệu trong lập trình C/C++ (Data type)

Kiểu dữ liệu Enum

Kiểu dữ liệu Enum trong ngôn ngữ C hay còn gọi là kiểu dữ liệu cố định, kiểu liệt kê. Giá trị của một Enum chỉ có thể nhận giá trị là một số các số nguyên cho trước.

Kiểu Enum này khá giống với kiểu Enum trong Java, Node.js hay Python…

Kiểu dữ liệu Void

Kiểu void dùng xác định không có giá trị nào (không phải là null).

Nó được sử dụng trong các trường hợp sau đây:

  • Kiểu trả về của một hàm: khi một không trả về dữ liệu gì thì hàm đó có kiểu void

Ví dụ:

void hello() {
printf("hello world");
}
  • Hàm với tham số void (tức là hàm không có tham số đầu vào)

Ví dụ: 2 cách viết dưới đây tương đương nhau:

void hello() {
printf("hello world");
}
// tương đương với
void hello(void) {
printf("hello world");
}
  • Con trỏ kiểu void void * được dùng để tham chiếu thới địa chỉ của một đối tượng (chứ không phải là một kiểu dữ liệu mới. Phần này hơi khó hiểu mình sẽ có bài riêng)

Kiểu dữ liệu nâng cao

Các kiểu dữ liệu nâng cao của C gồm:

  • Con trỏ (pointer)
  • Kiểu mảng (array)
  • Kiểu cấu trúc (structure)
  • Kiểu union
  • Kiểu hàm (function)

Kiểu dữ liệu boolean

Kiểu dữ liệu Boolean là một kiểu dữ liệu có chỉ có thể nhận một trong hai giá trị như đúng/sai (true/false, yes/no, 1/0) nhằm đại diện cho hai giá trị thật (truth value).

Trong lập trình C kiểu boolean sẽ được gọi là bool (trong Java thì gọi là boolean, trong Python thì gọi là bool… tùy theo ngôn ngữ)

Ban đầu, ngôn ngữ C không hỗ trợ kiểu bool, mà nó dùng số integer để biểu thị true/false (0 tức là false, khác 0 tức là true). Bắt đầu từ phiên bản C99 standard for C language thì mới bắt đầu hỗ trợ kiểu bool.

Lưu ý

Kiểu String

C/C++ không có loại dữ liệu string (text) dùng để hiển thị văn bản. Để hiển thị các giá trị kiểu text/string, ta dùng kiểu char. Thực chất char vẫn là kiểu số, nhưng tùy theo giá trị mà nó được hiểu thành các ký tự trong bảng mã ASCII. Một đoạn text/string trong C/C++ sẽ là một mảng char

Ví dụ số 32 tương ứng với dấu cách, 48 tương ứng với ký tự '0', 65 tương ứng với ký tự 'A'.

Để hiển thị đoạn text ‘hello’ thì ta cần mảng char tương ứng là [104, 101, 108, 108, 111]

Kiểu bool

Trong lập trình C, thực chất bool chính là kiểu integer (0 tức là false, khác 0 tức là true)

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

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

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

Tìm hiểu before và after trong CSS

Tìm hiểu before và after trong CSS

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

Hey ya. Tình hình là mới đi du lịch Đà Nẵng zìa hôm kia nên hôm nay tranh thủ viết bài chia sẻ tiếp kiến thức cho anh em. Và chủ đề hôm nay đó là một trong những pseudo class mà nhiều bạn học và làm vẫn chưa hiểu rõ cũng như áp dụng hết sự hiệu quả của nó mang lại đó chính là :before và :after.

Hiểu đơn giản thì before thì thêm vào trước và after là thêm vào sau thế thôi nhưng để hiểu sâu và làm được với nó thì cách tốt nhất đó là làm ví dụ thì mới mau hiểu được. Nào cùng chiến thôi.

  3 điều bạn có thể không biết về biến trong CSS
  9 CSS animation mới "mãn nhãn" cho các project

Đừng quên tham khảo khoá học HTML CSS cực chất mới ra mắt của mình tại đây: https://evondev.com/khoa-hoc-html-css

# Cách sử dụng

Để sử dụng :before hay :after thì đơn giản các bạn chỉ cần dùng theo cú pháp element:before hoặc element:after. Như .home:before{} chẳng hạn. Và để before hay after hoạt động thì bắt buộc phải có thuộc tính content nha.

Thường thường các bạn hay thấy content: "" người ta để rỗng thế này là vì người ta muốn làm một cái gì đó khác mà không có nội dung bên trong. Còn bạn muốn thêm vào content: "noidung" thì vẫn được không sao cả. Ví dụ một thẻ p nào đó

<p>toi ten la</p>

Mình muốn thêm tên của mình vào phía sau thẻ p này thì mình sẽ sử dụng :after

p:after {
content: " Tuan";
}

Còn nếu mình muốn thêm vào trước thì dùng :before

p:before {
content: "Xin chao ";
}

Ta được kết quả như hình

Tìm hiểu before và after trong CSS

Hoặc các bạn có thể thấy rõ khi các bạn sử dụng fontawesome, họ xài before hay after để hiển thị icon với thuộc tính content: "\ec06" gì đó để nó hiển thị icon tương ứng mà họ đã định dạng trong code của họ.

Còn nếu mà để trống content: "" như này thì các bạn cũng có thể làm nhiều kiểu style khác như làm background phủ toàn bộ layer nè, hiệu ứng background chạy qua chạy lại rồi animation các kiểu, tạo những kiểu phức tạp…. nhiều lắm.

Thường thường khi sử dụng before hoặc after thì phần tử mà chúng ta đang làm nên sử dụng position: relative hoặc position: absolute. Sau đó trong :before hay :after các bạn dùng position: absolute và các thuộc tính toprightbottomleft để căn chỉnh vị trí cùng với các thuộc tính CSS khác để style theo ý muốn của bạn.

Nếu bạn không hiểu cách dùng position trong CSS như thế nào thì đừng quên quay lại bài trước mình có viết về tìm hiểu thuộc tính position trong CSS rất rõ ràng chi tiết luôn ấy. Các bạn có thể xem tại đây nha.

Giờ mình sẽ làm vài ví dụ kèm theo giải thích cho các bạn dễ hiểu và hình dung hơn. Chớ đọc chữ nãy giờ chắc chưa thông não đâu.

# Hiệu ứng background

Giả sử bây giờ mình có HTML như thế này

<h2>Animation background</h2>

và CSS như này

h2 {
  display: block;
  margin: 50px;
  padding: 10px;
  color: black;
  font-weight: bold;
  position: relative;
}
h2:before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 100%;
  background-color: #e74c3c;
  transition: .25s;
}

Giờ mình muốn khi rê chuột vào thì cái background-color nó sẽ chạy từ trái qua phải rồi sau khi đưa chuột ra thì background-color nó thu về lại. Mình sẽ code như sau

h2:hover:before {
  width: 100%;
}

Lúc đầu mình cho :before có thuộc tính content: "" rỗng, position: absolute để chạy theo phần tử cha(ở đây là thẻ h2 chính nó) và  top: 0left: 0 thì nó sẽ nằm góc bên trái trên cùng

Kèm theo là height: 100% nghĩa là nó sẽ chiếm chiều cao 100% của phần tử mà chúng ta đang làm là thẻ h2 và set độ rộng(width) là 0 để nó chưa có gì hết. Và kèm thêm transition để làm hiệu ứng nó mượt hơn khi :hover vào.

Sau đó mình dùng :hover để khi chúng ta rê chuột vào thì mình cho độ rộng(width: 100%) để cho cái background-color nó chạy ra từ trái qua phải. Bạn có thể xem demo Codepen này

Tuy nhiên các bạn sẽ thấy khi rê chuột vào background-color nó chạy đè lên chữ luôn. Như vậy là sai rồi. Vì thế đừng quên dùng thuộc tính z-index vào nhé. Ở trong Codepen các bạn check code CSS sẽ thấy mình có comment cái z-index: -1 lại đó.

Mình để số âm là vì muốn nó nằm dưới, z-index hoạt động như các lớp đè lên nhau lớp nào có z-index cao hơn sẽ nằm lên trên và ngược lại lớp nào có z-index thấp hơn sẽ nằm ở dưới.

Mặc định giá trị của z-index là auto và z-index chỉ hoạt động khi đi kèm với thuộc tính position nhé. Cho nên mình set cho thẻ h2:before là -1 cho nó nằm dưới text. Các bạn nhớ bỏ comment để nó hiển thị ra kết quả như mong đợi nè.

Giờ mình muốn cải thiện hiệu ứng độc đáo hơn một chút với các thuộc tính left right các bạn có thể xem tham khảo nà. Mình muốn khi rê chuột vào background-color nó sẽ chạy từ trái qua phải(như lúc đầu) và sau khi bỏ chuột ra thay vì co background-color lại bên trái thì mình muốn nó chạy qua bên phải luôn.

Chỉ một chút thay đổi code CSS với thuộc tính left và right như thế này

h2:before {
  content: "";
  position: absolute;
  top: 0;
  left: auto; /*change here*/
  right: 0;/*change here*/
  width: 0;
  height: 100%;
  background-color: #e74c3c;
  transition: .25s;
  z-index: -1;
}
h2:hover:before {
  width: 100%;
  left: 0;/*change here*/
  right: auto;/*change here*/
}

Và ta được kết quả như mong đợi

# Lưu ý : và ::

Nhiều bạn khi code sẽ thấy có người dùng :before hoặc ::before thì mình note phát là hầu hết các trình duyệt đều hỗ trợ 2 dấu 2 chấm :: hay 1 dấu 2 chấm : cho cú pháp của CSS3 tuy nhiên trên một số trình duyệt cũ như IE8 chẳng hạn thì lại không hỗ trợ 2 dấu 2 chấm ::.

Cho nên nếu dự án bạn code không cần tới tận IE8 thì thoải mái dùng ::before hay ::after ok nhé. Còn làm việc với IE8 thì dùng :before hay :after cho an toàn.

# Tạo ribbon hình tam giác

Tìm hiểu before và after trong CSS

Các bạn nhìn quen không? Chắc hẳn khi làm sẽ gặp nhiều trường hợp như thế này rồi. Và cách tốt nhất đó là dùng :before hoặc :after để làm nó. Để tạo hình tam giác bằng CSS hay hình gì khác thì các bạn có thể tham khảo code tại đây.

Và chúng ta sẽ code HTML và CSS như thế này

<div class="quote"></div>

Ta được kết quả như mong đợi

Việc tạo hình tam giác thì mình đã để link ở trên, còn ở đây mình có set bottom: -10px để nó nằm dưới cùng vì nó có độ cao là 10px của border và mình cho thêm left: 50px để nó cách ra so với bên trái 1 chút cho đẹp và màu border nó sẽ trùng với màu nền của thẻ div mà chúng ta đang làm cho đồng bộ.

# Lời kết

Bài viết đến đây là kết thúc. Hi vọng sẽ giúp được cho các bạn hiểu hơn được đôi chút. Vì mấy cái này cần làm nhiều thì mới biết nhiều, áp dụng được nhiều chứ không thể chỉ hết được vì nó còn rất nhiều cái mới mà trong khi làm chúng ta sẽ gặp phải.

Nếu có gì thắc mắc góp ý thì cứ bình luận bên dưới mình sẽ ráng giải đáp với kiến thức chuyên môn của mình nà. Chúc các bạn một ngày tốt lành.

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

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

Xem thêm các việc làm lập trình CSS hấp dẫn tại TopDev

Import lodash như thế nào mới đúng

Import lodash như thế nào mới đúng

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

Mình đã từng nghe một bạn Principle FE trong công ty phát biểu là

Đã 2020 rồi mà còn xài lodash là sao, lodash đã tối cổ, chả ai xài nữa đâu

Khoan bàn chuyện đúng sai trong phát biểu này, nếu bạn cũng như mình, vẫn đang dùng lodash thì bạn cần biết import nó như thế nào cho đúng

Tại sao cần làm đúng? Vì nếu làm sao vô tình bạn sẽ làm phình cục bundle lên gấp mấy chục lần

  PHPExcel - Import và Export xử lý Excel
  20 trường hợp sử dụng lệnh Docker cho developer

Giờ so sánh 3 cách import

Cách 1

import _ from 'lodash';

Tại sao lại chọn kiểu này? Không cần quan tâm đến user, cảm giác rất quyền lực như có găng tay vô cực, chỉ với _. chúng ta có tất cả mọi thứ.

Điểm yếu, đây là cách tuyệt đối nghiêm cấm, vì gần như là load nguyên cái thư viện

Import lodash như thế nào mới đúng

Tổng 190 KB, Lodash ngốn hết 72.5kb

Cách 2

import { map, each, get, set } from lodash;

Kiểu này ổn, dễ đọc, rất rõ ràng để thấy được những hàm nào cần sử dụng.

Tuy nhiên, nó lại không khác gì với cách 1. Tổng vẫn là 190kb

Cách 3

import map from 'lodash/map';
import each from 'lodash/each';
import get from 'lodash/get';
import set from 'lodash/set';

Kết quả cho thấy đây là cách tiết kiệm nhất, mặc dù thực tế sử dụng cho thấy cách này hơi tốn công anh em dev của chúng ta và nhìn đoạn import có vẻ dài.

Import lodash như thế nào mới đúng

Một số ý kiến cho là dùng lodash-es, một phiên bản theo kiểu ES module sẽ tiết kiệm hơn, đây là kết quả đo được

  1. Cách 1: 256.4 KB
  2. Cách 1: 256.54 KB
  3. Cách 1: 142.39 KB

Như vậy việc dùng lodash-es có vẻ là vô dụng

Dùng lodash babel plugin

Sử dụng lodash babel plugin chúng ta có kết quả 140kb trên tất cả các cách import

Import lodash như thế nào mới đúng

Dùng Lodash webpack plugin

Lodash webpack plugin không biết đã bùa chú kiểu gì mà kết quả cuối cùng rất ngon 121kb cho cách 1, các cách khác sẽ còn bé hơn nữa

Kết luận

Nếu ko siêng bạn nên dùng cách 3, còn nếu siêng bạn setup với babel-plugin-lodash và lodash-webpack-plugin để đạt hiệu quả cao nhất.

Lodash-es thì nên dẹp luôn đừng xài vì nó ko thay đổi gì tích cực cả.

The Correct Way to Import Lodash Libraries

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

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

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

Chiến lược thúc đẩy động lực cho nhân viên

động lực

Động lực thực sự rất quan trọng đối với nhân viên. Động lực được xem là thứ nuôi dưỡng; thúc đẩy nhân viên về nhiều khía cạnh, đặc biệt là khía cạnh tinh thần. Hiệu suất cao, phát huy tiềm năng, khả năng đồng hành và phát triển,… là những yếu tố bị chi phối bởi động lực. Để đảm bảo việc duy trì động lực cho nhân viên, nhà quản lý/lãnh đạo nhân sự cần có những chiến lược cụ thể. Cùng TopDev tìm hiểu xem đâu là chiến lược phù hợp nhất.

Thiếp lập chính sách tiếp cận 

Hãy đảm bảo rằng nhân viên của bạn hiểu rõ về các quy tắc, (dựa trên các cơ sở pháp lý). Đồng thời, việc truyền đạt các chính sách phải diễn ra rõ ràng.

Nhà quản lý/lãnh đạo nhân sự cần xác định rõ nguyên nhân, kết quả và định hướng cho nhân viên những gì họ cần phải làm trong thời gian sắp tới.

  6 xu hướng giúp định hình những nhà lãnh đạo nhân sự tương lai
  Phân tích con người - Chiến lược quan trọng trong ngành Nhân sự năm 2023

động lực

Hơn thế nữa, nhân viên cần nhận thức được những ảnh hưởng phát sinh. Điều đó được phản ánh qua chính cách hành xử; thực hiện các nhiệm vụ của họ. Họ cần biết rằng khi họ đang hoạt động trong một tổ chức, việc giảm bớt cái tôi cá nhân và cân bằng hóa những mong muốn là ưu tiên hàng đầu. Hiểu được như vậy, mỗi nhân viên sẽ có được niềm tin từ doanh nghiệp. Đồng thời, hạn chế được những rủi tro phát sinh và có back-up phù hợp nhất cho tình hình hiện tại. 

Chuẩn hóa quản lý vĩ mô (Macromanagement)

Quản lý vĩ mô là một hình thức được nhiều doanh nghiệp dành sự quan tâm. Chuẩn hóa quản lý vĩ mô sẽ giúp chính các nhân viên kiểm soát tốt các nhiệm vụ cần phải thực hiện. Tự chủ động theo dõi và báo cáo kết quả. Và đảm bảo đúng trách nhiệm với nhiệm vụ được giao. Những quy tắc riêng được đặt ra khiến họ phải thật sự để tâm đến công việc của mình.

Xem thêm: Bí mật giúp tạo động lực và tăng năng suất cho nhân viên!

động lực

Từ cơ sở đó, hình thành ở họ một tư duy độc lập. Đặc biệt là tinh thần luôn cầu tiến. Họ biết rõ mình cần làm gì, làm vì mục đích nào và đâu sẽ là những đích đến xa hơn. Chính điều đó tạo ra động lực thúc đẩy họ luôn phải cố gắng.

Phép loại trừ là yếu tố được các tổ chức thực hiện nhằm gia tăng tính cạnh tranh. Thực tế mục đích của việc này là tạo ra “lực đẩy” tác động tinh thần. Từ đó, nhân viên nhân thấy các thách thức và tự nỗ lực rèn luyện. Thế nhưng, lưu ý mọi thứ cần có giới hạn. Nếu không, định hướng dẫn dắt và mục tiêu thực hiện quản lý vĩ mô sẽ bị ảnh hưởng.  

Khen thưởng luôn là chiến lược tối ưu

Không cần bàn cãi thì ai cũng thừa nhận rằng khen thưởng chính là cách tạo ra động lực tốt nhất dành cho nhân viên. Và tất nhiên, mỗi sự xem xét cần đảm bảo các tiêu. Mỗi quyết định đều dựa trên các hệ giá trị tnương ứng về khả năng, kinh nghiệm, hiệu suất công việc, tiềm năng phát triển,… Việc khen thưởng phải được diễn ra công bằng; đảm bảo tính hợp lý trong thị trường phát triển nghề nghiệp.

Xem thêm: Để thăng tiến, cần phải có chiến lược!

Động lực gắn liền với mục tiêu thăng tiến của mỗi nhân viên. Hãy mở ra nhiêu cơ hội để nhân viên thử sức. Họ sẽ cảm nhận được sự quan tâm nhiều hơn từ tổ chức.  Đó là động lực lớn giúp họ cải thiện hiệu suất công việc. 

Lời kết

Dưới góc nhìn của một chuyên gia, các nhà lãnh đạo nhân sự cần nhìn nhận những thay đổi cũng như mong muốn từ nhân viên. Họ cần một môi trường làm việc thoải mái và đảm bảo những nhu cầu về sự thăng tiến, tính hợp tác,… Rất nhiều thứ cần được nắm bắt qua chính lăng kính của người quản lý. TopDev hi vọng, nhà lãnh đạo sẽ giúp họ tiếp cận với các thách thức tạo ra động lực. Và cho họ niềm tin rằng tổ chức của bạn hoàn hoàn là nơi phù hợp giúp họ gia tăng động lực.


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

Có thể bạn quan tâm

Xem thêm Top các việc làm cho lập trình trên TopDev

Ngôn ngữ Java: Không bao giờ là quá trễ để học thêm về nó

ngôn ngữ java

Tác giả: John Selawsky

Chúng ta thường nghĩ rằng mình quá già để học thêm kiến thức mới hay quá lớn tuổi để nhảy việc. Thật ra tuổi tác chưa bao giờ là giới hạn để ta đạt được thứ mình muốn hay tiếp thu thêm kiến thức, như một ngôn ngữ lập trình mới chẳng hạn?

Tôi đã chứng kiến nhiều người trên 30 tuổi mới bắt đầu học về Java. Sự thật là càng lớn tuổi bạn càng có nhiều kinh nghiệm và khôn ngoan hơn khi tiếp thu, chọn lọc những kiến thức mới. Thêm vào đó, IT là lĩnh vực ít bị tác động bởi tuổi tác vì ngành này quan trọng kinh nghiệm của lập trình viên hơn.

Việc làm Java lương cao cho bạn

Bài viết này sẽ chia sẻ những lý do bạn nên bắt đầu học thêm về ngôn ngữ Java và cũng có thể áp dụng tốt cho việc học các ngôn ngữ lập trình khác.

topdev

Xem thêm Lập trình Java cho những người mới bắt đầu: học Java để làm gì?

Các lý lo nên bắt đầu học thêm về ngôn ngữ Java

Học những điều mới khi lớn tuổi sẽ giúp bạn xử lý công việc tốt hơn

Các nghiên cứu y khoa gần đây của Cesar Quililan đã chứng minh được ảnh hưởng đáng kể của hoạt động não bộ đối với quá trình lão hóa và sức khỏe não bộ. Nghĩa là nếu bạn càng rèn luyện trí não nhiều đầu óc bạn sẽ càng minh mẫn hơn. Nghiên cứu cũng chỉ ra rằng những người ở độ tuổi 60 – 90 đã cải thiện sức khỏe não bộ của họ chỉ bằng cách làm đồ thủ công mỹ nghệ và một số sở thích chỉ vài giờ mỗi ngày. Vậy bạn có thể tưởng tượng xem bộ não của một người 30 tuổi sẽ còn làm được nhiều việc như thế nào?

  10 lý do cho thấy tại sao bạn nên theo học ngôn ngữ lập trình Java
  11 mẹo đơn giản để tăng hiệu suất Java cấp tốc

Khi học một ngôn ngữ lập trình mới não bộ sẽ rèn luyện khả năng suy nghĩ và vận dụng đầu óc, từ đó tăng sự tập trung và chú ý của bạn. Một người đàn ông 32 tuổi chia sẻ trên Reddit rằng trước đây anh ấy không hề biết về lập trình hay kỹ năng nào, tuy nhiên hiện tại anh ấy đang học lập trình ở trường đại học. Dù bắt đầu có nhiều khó khăn nhưng giờ đây đầu óc anh ấy đã nhạy bén hơn rất nhiều. Và chẳng ai quan tâm xem anh ấy bao nhiêu tuổi cả!

Có rất nhiều khóa học và tài liệu học trực tuyến – ở đó chẳng ai quan tâm đến tuổi của bạn!

Học trực tuyến không còn là khái niệm mới và thậm chí nhiều người còn cảm thấy nó hiệu quả hơn cả học offline. Ngành IT coi trọng kiến thức và kỹ năng hơn là khả năng thể chất của bạn. Nếu thật sự muốn học hỏi bạn sẽ thành công và đạt được công việc mơ ước rất nhanh.

Xem thêm Cẩm nang tri thức dành cho sinh viên ngành IT

Dưới đây là những nền tảng trực tuyến mà bạn có thể sử dụng để học thêm Java: 

CodeGym – cung cấp khóa học lập trình Java trực tuyến với 80% tiết học thực hành, được thiết kế cho các beginner.

topdev

CodeAcademy – chương trình này cung cấp các kỹ năng mang tính kỹ thuật rất hữu ích trong công việc tương lai của bạn.

ngôn ngữ java

Khi bạn bắt đầu học hay tìm hiểu ngành lập trình, bạn vẫn cần tham khảo thêm khá nhiều các nguồn kiến thức hay kinh nghiệm từ những dev đi trước. Đây là một số trang web cung cấp nhiều kiến thức về ngôn ngữ lập trình Java mà bạn có thể tham khảo:

Java subreddit là nền tảng chia sẻ các giải pháp và kinh nghiệm về các vấn đề liên quan đến Java.

Java world là nền tảng chứa rất nhiều tin tức, blog, chia sẻ của chuyên gia liên quan đến Java.

Programming subreddit là nền tảng cho phép bạn đặt câu hỏi hoặc được giải đáp các thắc mắc liên quan đến việc lập trình.

Java Forum là một diễn đàn quen thuộc của các dev có nhiều chủ đề và được chia thành từng phần để tìm kiếm nhanh hơn.

Java Geek là một chương trình mà bạn có thể tìm thấy những lời giải thích rõ ràng về một trường hợp hoặc một vấn đề cụ thể, ngoài ra nó còn được chia thành các danh mục tương tác với các lĩnh vực công nghệ khác nhau.

CodeGym Help là một cộng đồng dành cho những beginner, nơi họ có thể chia sẻ những khó khăn và được hỗ trợ kịp thời.

Bench Resources là nơi các tập hợp các vấn đề liên quan đến Java.

Ngoài ra còn có các khóa học video trực tuyến trên Coursera hoặc Udemy – đây là những nền tảng bao gồm các khóa học trực tuyến từ các trường đại học ở khắp nơi trên thế giới, dành cho nhiều đối tượng khác nhau.

ngôn ngữ java

Bên cạnh đó, còn có một nguồn kiến thức quan trọng khác mà bạn không nên bỏ qua đó là sách. Bạn có thể tham khảo một số cuốn như:

Head First Java by Kathy Sierra & Bert Bates: Các tác giả của sách này cố gắng truyền tải những kiến ​​thức họ có bằng một ngôn ngữ đơn giản và nội dung trực quan cho người đọc tìm hiểu về Java.

Java: A Beginner’s Guide by Herbert Schildt: mô tả những điều cơ bản của ngôn ngữ lập trình Java theo thứ tự từ dễ đến khó, cho phép người dùng hiểu và đi sâu vào ngôn ngữ Java ngay từ đầu.

Đây chỉ là một ít trong số rất nhiều nguồn khác nhau về ngôn ngữ lập trình Java mà bạn có thể học. Hãy tìm hiểu về nó ngay khi có thể vì chẳng ai quan tâm đến tuổi tác của bạn cả mà họ chỉ quan tâm đến những gì bạn biết mà thôi.

Tuổi tác không liên quan

Tuổi tác chỉ là con số. Nhưng nhiều người lại có suy nghĩ sẽ gắn bó với một công việc cho đến cuối đời. Hãy thay đổi quan điểm này và bắt đầu làm mọi thứ mà bạn muốn, hãy bắt đầu học lập trình nếu bạn muốn trở thành lập trình viên. 

Đừng so sánh với người khác. Bạn và người đó có xuất phát điểm và kinh nghiệm làm việc khác nhau. Thay vào đó, hãy tự so sánh mình của hiện tại với trước đây, nếu chăm chỉ luyện tập bạn sẽ thấy rõ sự tiến bộ của mình.

  "Code dễ đọc" là như thế nào?

Và đừng bao giờ sợ code xấu hay thiếu kinh nghiệm vì dù ở độ tuổi nào chăng nữa chúng ta vẫn mắc lỗi khi mới bắt đầu công việc và sẽ dần cải thiện khi trau dồi kỹ năng nhiều hơn. Các công ty tuyển dụng đều yêu cầu ứng viên có kinh nghiệm ở mức tối thiểu và sẽ cải thiện thêm trong quá trình làm việc. Vì chúng ta không thể học tất cả mọi thứ chỉ trong một lần, thời gian là điều cần thiết để mọi người nâng cao “tay nghề” của mình.

ngôn ngữ java

Học Java cũng giống như học các kỹ năng khác mà thôi

Học Java cũng không khác gì tập đi xe đạp, chỉ là bạn sẽ lo lắng nhiều hơn khi học đi xe đạp ở tuổi trưởng thành. Ở tuổi trưởng thành bạn sẽ còn có nhiều kinh nghiệm hơn khi đối mặt với những khó khăn và biết cách vượt qua nó tốt hơn.

Không thời điểm nào học ngôn ngữ java tốt hơn ngay bây giờ

Đừng trì hoãn những dự định của bạn, hãy bắt tay vào thực hiện ngay khi có thể vì sẽ không bao giờ có thời gian thích hợp hơn ngay bây giờ cả. Bạn sẽ lãng phí thời gian nếu chờ đợi đến lúc thích hợp. Thậm chí khi càng lớn tuổi hơn bạn sẽ càng hoài nghi nhiều hơn với những thứ mình làm. Mạnh mẽ và dám đối mặt sẽ giúp bạn sớm đạt được thành công.

Kết luận 

Không bao giờ là quá muộn để bắt đầu học ngôn ngữ lập trình Java hay bất cứ ngôn ngữ lập trình nào khác. Hãy bắt đầu càng sớm càng tốt vì IT là ngành rất coi trọng kiến thức và kĩ năng. Đủ bản lĩnh sẽ giúp bạn thành công trong công việc lập trình viên này.

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

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

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