Home Blog Page 143

Một số thủ thuật hay trong Python

thủ thuật python

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

Copy một list

Giả dụ chúng ta có đoạn code sau:

>>> A = [1, 2, 3, 4, 5]
>>> B = A

thì nếu chúng ta in list B thì sẽ được các phần tử của list A, nhưng thực ra B chỉ là một biến tham chiếu đến A trong bộ nhớ, tức là thực chất trong bộ nhớ chỉ có 1 list [1, 2, 3, 4, 5] và cả A và B cùng trỏ đến list đó chứ không phải A và B có 2 list giống nhau.

  71 trích đoạn code Python cho các vấn đề hàng ngày của bạn
  Bỏ túi cheatsheet dành cho Python newbie
>>> C = A[:]

Còn trong dòng code trên thì chúng ta mới thực sự tạo ra một list khác là C có các phần tử giống như list A.

Bây giờ chúng ta thử đổi một phần tử trong list A:

>>> A[0] = 8
>>> A
>>> [8, 2, 3, 4, 5]
>>> B
>>> [8, 2, 3, 4, 5]
>>> C
>>> [1, 2, 3, 4, 5]

Rõ ràng khi in list A và B đều cho kết quả giống nhau vì chúng cùng tham chiếu tới một list, nhưng C thì lại khác vì các phần tử trong list C tồn tại độc lập.

Việc làm python các công ty lớn

Khởi tạo giá trị mặc định cho đối tượng Dictionary

Các đối tượng Dictionary được tạo ra là rỗng. Nhiều khi chúng ta làm việc với Dictionary mà không biết khóa đó có giá trị hay chưa nên truy xuất giá trị sẽ bị lỗi, do đó chúng ta có thể dùng phương thức get() rồi truyền thêm giá trị mặc định vào, tức là nếu khóa đó không có giá trị thì Python sẽ gán giá trị mặc định vào luôn.

>>> D = dict()
>>>> D['cat'] += 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'cat'
>>> D['cat'] = D.get('cat', 0) + 1
>>> D['cat']
1
>>> D['cat'] = D.get('cat', 0) + 1
>>> D['cat'] = D.get('cat', 0) + 1
>>> D['cat'] = D.get('cat', 0) + 1
>>> D['cat'] = D.get('cat', 0) + 1
>>> D['cat']
5
>>> D['dog'] = D.get('dog', 0) + 1
>>> D['dog'] = D.get('dog', 0) + 1
>>> D['dog'] = D.get('dog', 0) + 1
>>> D['dog']
3
>>> D
{'dog': 3, 'cat': 5}

Gán nhiều giá trị cùng một lúc

Bạn có thể gán một lúc nhiều giá trị vào nhiều biến. Tính năng này đặc biệt hữu ích cho việc hoán đổi giá trị giữa 2 phần tử. Với Python bạn không cần phải khai báo biến tạm như temp = a; a = b; b = temp; để thực hiện công việc hoán đổi giá trị nữa.

>>> x, y = 1, 2 #multiple assignment
>>> x
1
>>> y
2 
>>> x, y = y, x #swapping
>>> x
2
>>> y
1

>>> Xem thêm: Python cơ bản cho ứng dụng trong công việc

Có thể gọi bất cứ thứ gì

Chúng ta có thể hầu như gọi bất cứ thứ gì một cách ngẫu nhiên nhưng thường thì cũng không nên làm như vậy vì sẽ rất khó kiểm soát.

>>> number = '123'
>>> number*2
'123123'
>>> # hmmm ...
...
>>> int(number) * 2
246
>>> i = int
>>> i(number) * 2
246

Đặt tên biến Unicode

Để có thể sử dụng tên Unicode thì chúng ta viết code trong file script là lưu lại với định dạng UTF-8.

>>> biến = 1
>>> print(biến)

Truyện tranh Python

Bạn có thể import antigravity để… mở một trang truyện tranh về Python trên trình duyệt

import antigravity

python

Cú pháp for…else

Ví dụ:

for i in foo:
    if i == 0:
        break
else:
    print("Hello world!")

Cú pháp điều kiện

Thay vì dùng câu lệnh if..else như thường chúng ta có thể dùng nhanh cú pháp sau đây:

>>> x = 3 if(y == 1) else 2

Dòng trên có nghĩa là nếu y = 1 thì gán x = 3, ngược lại thì gán x = 2. Cú pháp này giống như toán tử ?: trong C++, Java… vậy.

Đảo Ngược Chuỗi

Thao tác đảo ngược một chuỗi trong Python có thể được thực hiện thông qua sử dụng kỹ thuật đơn giản sau:

site_domain =  "codehub.vn"
print site_domain[::-1]

Không có gì là phức tạp phải không nào.

Gán Giá Trị Cho Nhiều Biến Từ Phần Tử Trong Danh Sách

Giả sử chúng ta có một biến my_numbers với giá trị thuộc kiểu dữu liệu danh sách và gồm có 3 phần tử như sau:

my_numbers = [1,2,3]

Bây giờ để gán giá trị cho 3 biến mới lấy từ 3 phần tử của danh sách trên chúng ta làm như sau:

my_numbers = [1, 2, 3]
first, second, third = my_numbers

Bây giờ 3 biến first, second và third lúc này nhận 3 giá trị tương ứng là 1, 2 và 3.

Nối Các Phần Tử Trong Danh Sách Để Tạo Chuỗi

Giả sử chúng ta có biến my_list với kiểu dữ liệu danh sách như sau:

my_list = ["CodeHub.vn", "Learn", "Code", "Everyday"]

Để nối các phần tử trong chuỗi này bạn có thể làm như sau:

print " ".join(my_list)

Kết quả hiển thị của đoạn câu lệnh trên:

CodeHub.vn Learn Code Everyday

>>> Xem thêm: Tuyển tập chuẩn “sách giáo khoa” Python

“Zip” Phần Tử Của Hai Hay Nhiều Danh Sách

Giả sử bạn có hai danh sách như sau:

my_numbers = ['1', '2', '3']
my_numbers_in_english = ['first', 'second', 'third']

Và bạn được yêu cầu viết một đoạn code Python để hiển thị kết quả như sau:

1 first
2 second
3 third

Thì lúc này bạn có thể sử dụng hàm zip:

for a, b in zip(my_numbers, my_numbers_in_english):
    print a, b

Rất hữu ích phải không nào, chúng ta nhận được kết quả như ý muốn với số lượng đoạn code tối thiểu phải viết điểu này không phải lúc nào cũng dễ dàng với các ngôn ngữ script khác.

Chúc các bạn học tập tốt.

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

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

Xem thêm các việc làm it nhiều ngành nghề hấp dẫn tại TopDev

Selenium là gì? Một số kinh nghiệm làm việc với Selenium

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

1. Selenium là thuốc? Ồ không!

Selenium ở đây tất nhiên không phải là “Selenium là khoáng chất vi lượng quan trọng trong nhiều hoạt động như xử lý não bộ, miễn dịch và sinh sản

selenium
Không phải là thuốc nha mấy thím. Đang nhắc tới automation test tools

Selenium được nhắc tới trong bài viết là AUTOMATIONS TEST TOOLS (kiểm thử phần mềm hoặc website tự động).

Định nghĩa nhàm chán nhưng cũng cần phải biết là:

Selenium is an umbrella project for a range of tools and libraries that enable and support the automation of web browsers.

Selenium là dự án “ô dù” với mục đích tạo ra các công cụ (tools) và thư viện (libraries) tự động hóa các trình duyệt web.

Ngoài ra, một từ khóa quan trọng đễ dễ nhớ hơn là:

It provides extensions to emulate user interaction with browsers

Selenium cung cấp các tiện ích mở rộng mô phỏng sự tương tác của người dùng với browser.

Định nghĩa loằng ngoằng là vậy, nhưng với Selenium, ta có thể mô phỏng hầu hết những thao tác người dùng với trình duyệt (nhấp – click, cuộn – scroll, đóng tab, click check box, …)

selenium

2. Ưu điểm của Selenium

Hiện tại, danh sách Top 10 Automation Testing Tools đã bao gồm nhiều cái tên (mabl, randorex). Tuy nhiên, Selenium vẫn là một cái gì đó khó thay thế, vẫn nổi bật và có nhiều giá trị.

Giới QC trong giang hồ hẳn ai cũng biết về Automation test tools này. Vang danh khắp thiên hạ.

2.1 Hỗ trợ nhiều ngôn ngữ lập trình

Bản thân mình, trong quá trình làm việc cho công ty cũng được tiếp xúc với selenium một vài lần. Cụ thể là với Webdriver JavaJavascript và Python.

selenium
Hiện tại hỗ trợ tới 6 ngôn ngữ lập trình: Java, Python, C#, Ruby, JavaScript và Kotlin. So far, so good.
Nguồn/ Source: selenium.dev

2.2 Miễn phí – free

Khỏi phải nói, ưu điểm này thật sự là đáng tiền nhất của Selenium, so với các đối thủ khác như Ranorex hoặc MablSelenium hoàn toàn miễn phí. Chính vì vậy, nó thường được các doanh nghiệp IT Nhật Bản tin dùng.

Tất nhiên với Java, ta có ngay slogan quen thuộc: “Viết một lần – Chạy khắp nơi“, làm gì chả thích. “Run once time, run everywhere”.

2.3 Dễ hiểu, dễ sử dụng

2.4 Hỗ trợ đa trình duyệt với Webdriver

Selenium hỗ trợ test tự động trên nhiều browser. Hỗ trợ tốt khi khách hàng cần test trên nhiều phiên bản, nhiều loại browser khác nhau (thường thì chắc chắn sẽ yêu cầu như vậy).

Đối với môt số khách hàng từ Nhật hay cơ quan chính phủ, yêu cần website hoạt động tốt trên IE 9,10,11,. Việc viết test case một lần và chạy trên nhiều trình duyệt là vô cùng tiện lợi và nhanh chóng.

selenium
Hỗ trợ Internet Explorer, tin vui cho mấy anh em phát triển phần mềm chính phủ

2.5 Dễ dàng take evidence khi chạy

Thực tế khi làm việc, khách hàng lúc nào cũng yêu cầu evidence khi thực hiện chạy testcase.

Khi một website đã hoàn thiện để chạy automation test, nếu có lỗi xảy ra, ngoài ghi log hoặc báo file, yêu cầu cần thiết nhất luôn là chụp evidence (bằng chứng) ngay lúc đó.

Selenium hỗ trợ rất tốt cho những trường hợp muốn chụp lại màn hình. Kể cả trong trường hợp page ở website là scroll. Mình đã từng sử dụng Selenium để chụp những

3. Một số nhược điểm

Mặc dù có nhiều ưu điểm không phải automation test tools nào cũng có. Selenium vẫn tồn tại một số yếu điểm dưới đây:

3.1 Muốn chạy ổn, hãy cố handle timeout

Một nhược điểm cố hữu có các Automation test tools (không ngoại trừ Selenium) là timeout. Trường hợp sử dụng để kiểm thử cho websitetốc độ mạng có thể khác nhau giữa những lần chạy testcase. Chắc chắn là không giống nhau giữa các lần chạy.

Việc chạy automation test vào lúc mạng chậmtraffic đang stuck có thể làm fail một số testcase. Trong những trường hợp như vậy, cần xử lí tốt các trường hợp timeout.

Thực tế, trong quá trình làm việc, mình thấy các Exception Timeout thường do:

Mình đang test ở page 1 -> nhấn button A -> di chuyển tới page 2 -> tìm kiếm button B. Các hàm tìm kiếm có thể là (getElementById(), getElementByTag(), …).

Nuột nà là thế, nhưng do mạng chậm, nên lúc tới page 2 vẫn không tìm được button B -> văng Exception.

Trường hợp muốn handle exception, có thể đọc thêm bài viết này ở KieBlog.

3.2 Nếu không kiểm soát tốt, hết ram, chết đứng

Thông thường, mỗi testcase sẽ khởi chạy với một new instance của browser ta muốn chạy. Tuy nhiên, nếu có vấn đề, hoặc ta không thể handle các trường hợp cần đóng browser. Rất có thể có các trường hợp sau:

  • Không thể tìm đúng đối tượng trên browser do instance của browser cũ chưa tắt (close)
  • Quá tải ram do nhiều trình duyệt mở (nhất là chrome)
selenium
Không khó để tìm những câu hỏi rằng không thể đóng được browser đã mở.

Có rất nhiều nguyên nhân dẫn tới trường hợp này. Nếu trước đó đã có exception không được catch or throws, sẽ không thể close instance browser đã mở.

4. Tổng kết

Đọc tới đây, chắc hẳn các thím cũng có đã có cái nhìn “sơ sơ” về Selenium. Để hiểu sâu hoặc bắt đầu thực tế sử dụng, hãy chú ý xem các bài viết tutorials ở phần tham khảo.

Cảm ơn đã đọc bài của mình và hãy cố gắng sử dụng Selenium một lần cho biết nhé, nó bá đạo lắm đấy!.

Chỉ sau 15 tháng, Gameloft for brands và Kinder đã cho ra đời dự án đầy tham vọng – Applaydu

Applaydu hiện đã có thể tải xuống miễn phí từ App Store hoặc từ Google Play Store.

Chỉ sau 15 tháng, Gameloft for brands và Kinder đã ra mắt ứng dụng Applaydu – một dự án đầy tham vọng – mang các nhân vật đồ chơi của Kinder vào đời sống thực tế thông qua Thực tế tăng cường (AR) với một thế giới đầy những điều thú vị đang chờ được khám phá.

Applaydu là một ứng dụng giáo dục trên điện thoại, được thiết kế cho trẻ em từ 3 đến 9 tuổi. Tại đây, các bé có thể khám phá nhiều trò chơi đầy thú vị, giúp các bé học đếm, làm quen với ngôn ngữ và mở rộng kiến thức về các quốc gia, địa lý và cả động vật.

Một đoàn làm phim chuyên nghiệp đã đến thăm Gameloft Sài Gòn Studio để có thể nắm bắt được kĩ càng nhất quá trình phát triển suốt 15 tháng của dự án Applaydu. Qua đó, “Creating Applaydu” – một phim tài liệu dài 15 phút đầy gần gũi và cảm động đã ra đời, thể hiện cận nét từng bước hành trình sáng tạo của cả nhóm. Bạn sẽ nhận ra rằng chuyên môn và niềm đam mê của từng thành viên trong team có thể giúp họ đạt được những điều to lớn như thế nào.

Đội ngũ Applaydu tại trụ sở Gameloft Sài Gòn Studio

Thế giới đã thay đổi rất nhiều kể từ khi Kinder Surprise phát hành cách đây 50 năm: trẻ em ngày nay được sinh ra với công nghệ và dành phần lớn thời gian của chúng trên điện thoại thông minh. Để bắt kịp với thời đại, Ferrero Group muốn nâng cao trải nghiệm của trẻ em bằng cách kỹ thuật số hóa những đồ chơi bình thường. Là một chuyên gia trong ngành công nghiệp game suốt 20 năm, Gameloft for brands đã giúp Ferrero đưa chiến lược của họ lên một tầm cao mới bằng cách tạo ra một ứng dụng, nơi mà trẻ em có thể vừa học vừa chơi. Đây cũng là dự án đầu tiên do Gameloft sáng tạo 100% bởi Gameloft for brands tại Sài Gòn.

Applaydu là một ứng dụng giáo dục trên điện thoại được thiết kế cho trẻ em

Một trong những thách thức lớn nhất là trò chơi được tạo ra cho các bé từ 3 đến 9 tuổi. Trong khi đó, trẻ 3 tuổi sẽ có mức độ phát triển khác với trẻ 9 tuổi, hay thậm chí 2 đứa trẻ ở cùng độ tuổi có thể có những mức độ phát triển khác nhau. Từ đó, nhóm đã đưa ra giải pháp, rằng độ khó trong trò chơi sẽ tự động thay đổi dựa trên các lần chơi trước của trẻ, vì vậy việc lựa chọn mức độ trò chơi sẽ không còn là mối bận tâm của bố mẹ nữa.

Một thách thức khác của Applaydu là các bé ở độ tuổi đang phát triển sẽ không hiểu các cơ chế trừu tượng, biểu tượng hoặc trò chơi như người lớn. Vì vậy, giao diện người dùng và trải nghiệm người dùng (UX / UI) phải thật đơn giản và dễ hiểu.

Menu chính của Applaydu được thiết kế như phòng ngủ của các bé

Nhóm còn muốn cung cấp cho các bé một vũ trụ hữu hình, một nơi mà trẻ có thể “chạm vào”, và trong đó những sáng tạo của trẻ sẽ trở thành hiện thực. Nhóm cũng đã nảy ra ý tưởng về một thế giới thủ công, được làm từ những đồ vật trong đời sống (hộp đựng giày, bưu phẩm, bìa cứng,…) giúp tạo ra những sản phẩm sáng tạo mà ngay cả những đứa trẻ cũng có thể tự làm được. “Trên hết, chúng tôi muốn truyền cảm hứng cho các bé. Giờ đây, các bé có thể xây dựng thế giới của riêng mình ngay tại nhà bằng cách sử dụng mọi thứ ở xung quanh.” – Cédric Ratajczak, Giám đốc Sáng tạo cho biết.

Với tham vọng mang đồ chơi vào cuộc sống theo đúng nghĩa đen và tạo ra một kết nối riêng giữa trẻ em và đồ chơi của chúng, đội ngũ Applaydu đã dựa trên hình ảnh ban đầu của đồ chơi và khuếch đại các đặc điểm của chúng. Có thể dễ dàng nhận ra rằng tất cả các thiết kế nhân vật đều đồng nhất với đồ chơi của Kinder cũng như thể hiện được thế giới vui nhộn của Applaydu.

Đội ngũ Applaydu trong quá trình làm việc

Là một trong những nhà phát hành game di động hàng đầu thế giới, Gameloft luôn có trách nhiệm với sản phẩm của mình, đặc biệt là với trẻ em. Chính vì thế, đội ngũ vận hành đã hợp tác với các chuyên gia giáo dục hàng đầu tại Đại học Oxford để đảm bảo những câu chuyện trong Applaydu sẽ trở thành một công cụ hỗ trợ phụ huynh trong việc dạy học cho bé. Applaydu hiện đã chính thức nhận được Chứng nhận Ứng dụng Giáo dục (EAS) và Chứng nhận kidSAFE + COPPA.

Tham khảo các việc làm game cho bạn: Game Artist, Game Editor

Nói về Gameloft, studio đầu tiên tại Việt Nam được mở vào năm 2004, với tham vọng đưa các game của Gameloft lên tất cả các thiết bị di động hiện có. Cho đến nay, sau 16 năm phát triển, với chuyên môn của mình, đội ngũ sáng tạo của Gameloft for brands tại Sài Gòn đã cùng nhau tề tựu tại đây để mang đến một sự bùng nổ – ứng dụng Applaydu dành cho Kinder! Đứng sau Applaydu là đội ngũ gồm 50 nhân tài đến từ Sài Gòn Studio, một trong những studio Gameloft lớn nhất thế giới. Thierry Lecat, Giám đốc điều hành, cho biết: “Các thành viên trong nhóm đều trẻ trung và tràn đầy năng lượng. Chúng tôi được coi là một ‘team quốc tế’ vì có tới 9 quốc tịch với nhiều xuất thân khác nhau, nhưng chúng tôi đều có cùng nghị lực, cùng tinh thần đồng đội, cùng tư duy và luôn mang thái độ tích cực trước bất cứ mọi khó khăn”.

Applaydu hiện đã có thể tải xuống miễn phí từ App Store hoặc từ Google Play Store.

Quy chuẩn đặt tên trong lập trình: camelCase, underscore hay PascalCase?

đặt tên

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

Trong lập trình quy chuẩn đầu tiên cần đưa ra là quy chuẩn cho việc đặt tên. Có hàng tỉ thứ cần đặt tên trong lập trình, nói chơi vậy thôi chứ phân loại ra khoảng hơn chục thôi à, ví dụ như tên Class, tên biến, tên phương thức, tên thuộc tính… Có 3 chuẩn để đặt tên là underscore, camelCase và PascalCase.

  10 câu nói cực hay về lập trình
  10 lý do cho thấy tại sao bạn nên theo học ngôn ngữ lập trình Java
  • underscore: sử dụng dấu gạch chân giữa các từ, tất cả các từ đều viết thường, ví dụ: $this_is_my_variable.
  • camelCase: giống như cách viết của nó, từ đầu tiên viết thường, các từ tiếp theo viết hoa chữ cái đầu, ví dụ $thisIsMyVariable.
  • PascalCase: viết hoa tất cả các chữ cái đầu, ví dụ $ThisIsMyVariable.

Các quy chuẩn đặt tên thông thường

Sau đây là một số quy chuẩn đặt tên thường dùng trong dự án:

  • Tên lớp đặt theo PascalCase, ví dụ: UserClass, CategoryClass…
  • Tên hàm và phương thức sử dụng camelCase, ví dụ getUser, getCategory…
  • Tên biến cũng sử dụng camelCase loginUser,loginUser,categoryList…
  • Tên hằng số thì đặc biệt, viết hoa hết và cách nhau bởi dấu gạch dưới DISCOUNT_PERCENT, LIMIT_RATE…
  • Tên bảng, tên cột trong Database sử dụng underscore và sử dụng danh từ số nhiều, ví dụ bảng oauth_clients, oauth_refresh_tokens.
  • Tên phần tử trong HTML, ví dụ khi bạn sử dụng Vue.js, React… tạo ra thì nó sẽ có dạng KebabCase, ví dụ <my-component>.

Đặt tên là để gợi nhớ, ví dụ khi gọi đến tên của bạn là người ta biết ngay đó là bạn mà không nhầm sang người khác, đặt tên trong lập trình cũng vậy cần phải tường minh. Trước đây tôi có một người bạn trong cùng cơ quan đặt tên các biến khá thú vị: heheheeeee,heheheeeee,hihiiiiii… vãi cả nón, khi đọc code bò lăn ra cười, nói vui vậy thôi chứ như vậy là không nên, không thể hiểu được các biến này dùng làm gì, đặc biệt hơn nữa là khi xử lý qua lại đánh tên các biến này khó vãi, chắc phải copy cho chắc ăn.

Lời kết

Bạn nên tập thói quen đưa ra một quy chuẩn đặt tên trong lập trình của riêng mình, như vậy khi làm việc theo nhóm các thành viên khác có thể dễ dàng đọc được code của bạn. Hơn nữa, các thư viện mã nguồn mở hiện nay đều tuân thủ theo những quy ước đặt tên, nếu bạn không muốn mình tách rời với cộng đồng hãy tuân thủ theo “pháp luật”.

Bài viết gốc được đăng tải tại allaravel.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 Unit Test trước khi Code – tại sao không?

unit test

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

Ngược ngạo VCL, rõ ràng là phải viết code rồi mới có cái mà test chứ, viết Unit test trước thì run bằng mắt à?. Đấy, lần đầu tiên tìm hiểu kĩ thuật này tôi cũng đặt ra câu hỏi như các ông!.

Vấn đề là mình nghĩ thế nhưng nó lại không phải như thế. Viết Unit Test trước khi Implement là một trong những ý tưởng chủ chốt của TDD (Test Driven Development).

  "Code dễ đọc" là như thế nào?
  24 code ES6 tân tiến để khắc phục các lỗi thực hành JavaScript
unit test
TDD Introduction – Có đọc qua mới biết nha. Nguồn/Source: Medium

Thực chất thì có nhiều cái lợi lắm nha. Để tôi kể cho nghe:

1. Hiểu rõ những gì sắp code

Leader hay Br SE nhận requirements, hoặc là tự mình nhận (nếu làm freelancer bán thời gian như tôi). Với một số requirement đơn giản, không quá bự thì theo như thông thường

Đọc hiểu requirement -> code -> gửi QC hoặc Tester test -> Có bug -> Fix bug

Tuy nhiên, chỉ đọc hiểu requirement để code lại hoàn toàn khác với hiểu requirement để test. Ở tầm test của QC cần hiểu rõ về business, về những case sử dụng thực tế của khách hàng. Trường hợp sử dụng không normal sẽ xảy ra những bug nào?.

Developers have a clear target in mind and that’s very important in agile environment.

Lập trình viên có một mục tiêu rõ ràng trong trí óc là một điều rất quan trọng trong môi trường Agile

Chính vì vậy, viết unit test trước khi code là khoảng thời gian quý báu giúp bản thân xem xét những gì sắp làm. Cần code những gì?

2. Tránh chủ quan

Tại sao dev code thường có bug?. Trời má, thế giới nào mà không có bug?. Hỏi thừa quá ông ơi!.

Ý tôi là nhiều hay ít, ít bug thì rõ ràng dev đó cẩn thận hơn, kĩ tính hơn. Một trong những nguyên nhân lớn khiến dev có nhiều bug vì không tưởng tượng ra hết các kịch bản (scenarios) để test thử trước khi đem cho Tester.

Không những vậy, chủ quan còn mang tới những con bug basic hơn. Chính vì code và có niềm tin mãnh liệt vào code của mình, nên một số bạn để lọt bug do nghĩ chắc đoạn đó code ngon rồi, không bug đâu.

unit test
Thế giới nào lại không có bug!. Nguồn/Souce: monkeyuser.com

Sự thật thì. BUG, BUG SML

3. Rèn luyện tính cẩn thận khi viết Unit test

Áp dụng phương pháp này cho mấy thanh niên code ẩu thì khỏi bàn.

Nhiều khi cắm đầu code nhưng chỉ focus vào duy nhất một case (dân trong nghề gọi là happy case). Không quan tâm những case khác -> thành ra bug tè le.

Tuy nhiên nếu viết Unit Test trước, mọi chuyện rõ ràng dễ thở hơn nhiều. Trước khi bắt tay vào code phải lường trước những trường hợp có thể xảy ra.

unit test
Unit test vẫn là một trong những yêu cầu chính phải thực hiện nha!

Trở thành Senior Software Engineer không chỉ là code nhanh và xử lí task khó. Senior còn phải code ít bug, ít thời gian maintainance.

4. Lợi ích và hại ích

  • The test clearly defines what constitutes “done” – Rõ ràng được khi nào thì xong
  • The test documents how you intend the code to be used – Code được dùng như thế nào
  • Coding to meet a test case (and nothing else) helps keep you focused on one task and prevents feature creep – Không có các đoạn code dư thừa, chỉ focus làm sao cho match được testcase

Như một số lập trình viên vẫn truyền tai nhau:

“If I was given the choice of losing all of my code or all of my  tests, I would choose losing all of my code.”

Nếu được lựa chọn giữa mất toàn bộ code và toàn bộ test, tôi sẽ lựa chọn mất tất cả code của mình.

Tuy nhiên, phương pháp nào cũng phải một vài vấn đề. Đối với TDD (Test Driven Development), ta sẽ gặp một số vấn đề sau:

  • Viết Unit test không thể viết ẩu, viết ẩu sẽ để lọt case, mà lọt case là lòi BUG.
  • Người áp dụng phải có khả năng lường trước các vấn đề, tính cẩn thận.
  • Phải có thời gian (cái này quan trọng nhất).

Một số dự án bị dí SML, hoặc deadline dí tới đít thì code còn không kịp, lấy đâu ra thời gian mà ngồi viết testcase trước. Chính vì vậy, áp dụng kĩ thuật này cần có thời gian.

5. Tham khảo

Đã tìm hiểu về Unit test và kĩ thuật viết Test trước khi code thì tiện thể ngó qua luôn về Selenium Automation Test ở Kieblog. Khỏi phải giới thiệu dài dòng, những năm gần đây Automation Test đang trở nên hot vô cùng.

Hết rồi!. Nhớ like page và chia sẻ bài viết để ủng hộ tác giả nha. Happy coding!

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

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

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

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

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

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

Hai trong số các phương thức Danh sách phổ biến nhất trong Python là các phương thức “append” và “extend”

Tuy nhiên, hai phương thức này là nguyên nhân của rất nhiều nhầm lẫn và hiểu lầm giữa những người mới bắt đầu Python.

Trong bài viết này, tôi sẽ giải thích từng phương pháp làm gì và cho bạn thấy chính xác sự khác biệt giữa chúng.

Đầu tiên: Append

python

append phương thức được sử dụng để thêm một đối tượng vào một danh sách.

Đối tượng này có thể thuộc bất kỳ kiểu dữ liệu , chuỗi, số nguyên, boolean hoặc thậm chí một danh sách khác.

Giả sử bạn muốn  thêm  một mục vào danh sách L ban đầu có 4 phần tử

>>> L = [1, 2, 3, 4]
>>> L.append(5)
>>> L
[1, 2, 3, 4, 5]

Như bạn có thể thấy, phương thức chắp thêm mục 5 mới vào danh sách.

Không cần phải nói, độ dài của danh sách đã tăng thêm một (và chỉ một) vì phương thức chắp thêm chỉ thêm một đối tượng vào danh sách.

Đây là một sự khác biệt quan trọng bởi vì bạn sẽ thấy sau này không nhất thiết phải là trường hợp “extend” .

Được rồi, vì tò mò, hãy thử nối thêm một danh sách vào danh sách của chúng tôi.

>>> L = [1, 2, 3, 4]
>>> L.append([5, 6, 7])
>>> L
[1, 2, 3, 4, [5, 6, 7]]

Vì vậy, những gì chúng tôi đã làm ở đây là chúng tôi đã thêm một đối tượng (có thể thuộc danh sách loại) vào danh sách L của chúng tô.

Một lần nữa, sau khi sửa đổi, chiều dài danh sách chỉ tăng một.

Bây giờ hãy xem một phương pháp tương tự nhưng khác biệt.

  Function trong Python là gì? Tạo Function trong Python

Thứ hai: Extend

python

extend là một phương pháp danh sách rất phổ biến.

Không giống như chắp thêm có thể lấy một đối tượng thuộc bất kỳ loại nào làm đối số, phần mở rộng chỉ có thể lấy một đối tượng có thể lặp lại làm đối số.

Một đối tượng có thể lặp lại là một đối tượng mà bạn có thể lặp qua như chuỗi, danh sách, bộ dữ liệu, dicts hoặc bất kỳ đối tượng nào có phương thức __iter__

Những gì extend làm rất đơn giản, nó lặp đi lặp lại thông qua đối tượng lặp lại (iterable ) một mục tại một thời điểm và nối thêm từng mục vào danh sách.

Ví dụ: hãy thử mở rộng danh sách theo danh sách khác.

>>> L = [1, 2, 3, 4]
>>> L.extend([5, 6, 7])
>>> L
[1, 2, 3, 4, 5, 6, 7]

Như bạn có thể thấy trong ví dụ trên, extend sẽ lấy một danh sách (có thể lặp lại) làm đối số và nối từng mục của danh sách vào L.

Ba đối tượng số nguyên đã được thêm vào danh sách và kích thước danh sách tăng thêm ba.

Hành vi này rõ ràng là khác với phương pháp append .

Hãy xem xét một ví dụ khác với một đối tượng lặp khác, các chuỗi.

>>> L = [1, 2, 3, 4]
>>> L.extend("hi")
>>> L
[1, 2, 3, 4, 'h', 'i']

Điều tương tự!

extend lặp thông qua các ký tự  “hi” và gắn từng ký tự vào chữ L.

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

Lưu ý bên lề: Extend khác với Toán tử (+) như thế nào?

Một câu hỏi bạn có thể hỏi là phương thức mở rộng khác với sử dụng toán tử + như thế nào.

>>> L = [1, 2, 3, 4]
>>> L + [5, 6, 7]
[1, 2, 3, 4, 5, 6, 7]

Code ở trên dường như có cùng tác dụng mở rộng danh sách theo danh sách khác, phải không?

Vâng, có hai sự khác biệt chính:

1. bạn không thể sử dụng toán tử (+) để mở rộng danh sách bằng bất kỳ lần lặp nào khác ngoài danh sách

Ví dụ: bạn không thể sử dụng toán tử (+) để mở rộng danh sách bằng string hoặc tuple hoặc dist

2. extend sửa đổi danh sách tại chỗ trong khi toán tử (+) tạo danh sách mới

>>> L = [1, 2, 3, 4]
>>> L + [5, 6]
[1, 2, 3, 4, 5, 6]
>>> L
[1, 2, 3, 4]

Trong ví dụ trước, lưu ý rằng L hoàn toàn không thay đổi.

Điều này là do toán tử cộng tạo ra một đối tượng danh sách mới chứa danh sách được nối.

Để sử dụng danh sách kết quả, trước tiên bạn có thể cần lưu trữ nó trong một biến khác.

>>> c = + [56] >>> c [123456]

Phần kết luận

1- Cả extend và append là các phương thức danh sách được sử dụng để thêm các mục vào danh sách.

2- append  thêm một đối tượng thuộc bất kỳ loại nào vào danh sách.

3- extend hoạt động trên các đối tượng có thể lặp và nối thêm mọi mục trong lần lặp vào danh sách.

4- sử dụng toán tử (+) không tương đương với sử dụng phương thức extend.

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

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

Một vài điểm nên nhớ khi viết CSS

Một vài điểm nên nhớ khi viết CSS

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

Khoảng cách giữa title và icon

css

Phần chữ ở title có thể sẽ rất dài, về để tránh nó bị dính sát rạt với cái icon, thêm margin-right: 1rem

Tham khảo Việc làm CSS lương cao tại Topdev

2 button nằm kề nhau

Nếu có 2 button nằm kế nhau, 99,9999% chúng ta muốn giữa các button có khoảng trắng, dùng css selector adjacent-sibling

.button + .button {
    margin-left: 1rem;
}

Tag và Category

css

Trong trường hợp mà tag name và category name quá dài, nếu để nó dàn trải như trong hình, sẽ tốt hơn nếu cho nó rớt dòng

css

.tag {
    max-width: 6.25rem;
    text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
}

Không load được image

Nếu dùng thẻ <img /> mà nó ko load được hình thì sao, 1 cách cũng khá đơn giản là set background-color

css

img {
    background-color: #525252;
}

Hình Avatar

Đừng quên đặt object-fit: cover để có một hình tròn trịa đẹp đẽ như bên dưới, không bị stretch hay compressed

css

The Just in Case Mindset in CSS

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

6 tips quản lý thời gian hiệu quả

quản lý thời gian

Khối lượng công việc quá lớn khiến bạn trở nên mệt mỏi. Đó cũng chính là lý do bạn chưa biết cách quản lỳ thời gian hiệu quả. Do vậy, bạn tiếc nuối khi đã bỏ lỡ nhiều khoảng thời gian quý giá đó. 

Bài viết sau đây, TopDev sẽ chỉ ra cho bạn những cách thức giúp quản lý thời gian hiệu quả nhất. Việc này sẽ giúp bạn giảm căng thẳng và có biểu hiện tốt hơn ở nơi làm việc.

Ủy thác lại nhiệm vụ

Việc bạn đảm đương quá nhiều việc không còn là điều quá xa lạ. Chính việc không biết cách từ chối đã dẫn bạn đến tình trạng kiệt sức. Ủy thác được xem là cách thức phù hợp nhất để giải quyết tình trạng này. Tuy nhiên, điều này không có nghĩa là bạn trốn tránh trách nhiệm của mình.

quản lý thời gian

Hãy học cách ủy thác nhiệm vụ của mình xuống cấp nếu công việc quá nhiều. Việc ủy thác cũng có những điểm tích cực. Bạn sẽ tạo cho cấp dưới cơ hội làm việc phù hợp với năng lực và kỹ năng của họ.

Tính logic – Đảm bảo yếu tố ưu tiên

Mọi thứ sẽ hoàn hảo hơn nếu bạn có một kế hoạch cụ thể trước khi thực hiện. Nó có thể hiểu là một quá trình bao gồm các nhiệm vụ cần thực hiện. Chẳng hạn, nếu bạn muốn ứng tuyển các vị trí IT. Bạn cần tìm hiểu về công ty, loại hình hoạt động. Tiếp đó là chuẩn bị một CV IT tiếng anh hoặc tiếng việt. Đây là điều quan trọng. Bạn có thể sáng tạo CV riêng của mình trên các nền tảng CV online,…

quản lý thời gian

Điều quan trọng, bạn cần phân loại rõ đâu là việc quan trọng – đâu là việc khẩn cấp. Hãy cân nhắc thật kỹ để đảm bảo hiệu suất công việc cũng như các giá trị mang lại cho bản thân bạn.

Tạo CV IT tại đây

Lên lịch các nhiệm vụ để quản lý thời gian

Một cuốn sổ có thể giúp bạn ghi chép các ý tưởng bất chợt. Bạn có thể dùng các ý tưởng đó để hoàn thiện lịch trình thực hiện các nhiệm vụ. Một điều bạn cần lưu tâm khi lên lịch các nhiệm vụ là đảm bảo tính khả thi.

Xem thêm: 5 lưu ý để viết đánh giá hiệu suất của bạn

Để dễ dàng kiểm soát kỹ năng quản lý thời gian, bạn nên thiếp lập mọi thứ xoay quanh các chủ đề trọng tâm: Công việc, Gia đình, Cá nhân.

Hạn chế căng thẳng

Stress thường xuất hiện khi bạn quá mệt mỏi. Nguyên nhân đến từ việc bạn chịu ức ép quá lớn từ công việc. Bạn chưa biết cách quản lý thời gian hiệu quả. Và điều này sẽ ảnh hưởng đến năng suất của bạn. Do vậy, hãy thư giãn. Đừng để bản thân phải rơi vào tình trạng căng thẳng tột độ.

Xem thêm: Giải pháp cho những ai đối mặt với căng thẳng tại nơi làm việc

quản lý thời gian

 

Đặt ra các dealine

Dealine có ý nghĩa rất quan trọng đối với vấn đề quản lý thời gian. Khi thực hiện Khi một nhiệm vụ nào đó, hãy lên deadline cho nó và thực hiện theo. Hãy cố gắng hoàn thành một cách tốt nhất. Đừng trì hoãn với sự lười biếng vì bạn không lường trước được rất nhiều chuyện đột xuất sẽ xảy ra. Hãy thử thách bản thân và đáp ứng thời hạn. Đừng quên thưởng cho bản thân khi hoàn thành một thử thách khó khăn nhé!

quản lý thời gian

Bắt đầu sớm là cách để thành công

Dù bạn là ai, làm trong lĩnh vực gì thì việc bắt đầu sớm công việc với một tâm thế thoải mái, đó là bí quyết của sự thành công. Bạn không cần đắn đó quá nhiều thứ. Hãy bắt đầu bằng việc hít thở thật sâu. Bạn sẽ có thêm thời gian thư giãn, suy nghĩ và lên kế hoạch làm việc cho một ngày. Nguồn năng lượng làm việc rất quan trọng. Do vậy, hãy bắt đầu sớm với một tinh thần sảng khoái nhất. 

Lời kết

Hãy học cách nói từ chối khi bạn cảm thấy mọi thứ quá sức. Đó là lời từ chối lịch sự. Những cân nhắc về những điều mà cần làm, phải làm và sẽ làm. Cụ thể. phân biệt rõ những công việc quan trọng – ưu tiên để đạt hiệu suất công việc một cách tốt nhất. Mọi bí quyết đều chỉ là lý thuyết nếu bạn không áp dụng chúng vào thực tế. TopDev hy vọng, bài viết đã giúp bạn có những tip bổ ích cho việc quản lý thời gian và lập kế hoạch thực hiện các công việc.

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

Xem thêm Top tìm việc it cho các Developer trên TopDev

Mock API bằng Mirage JS

Mock API bằng Mirage JS

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

Tại sao bạn cần giả lập (mock) API

FE sẽ ko phải đợi đến khi BE làm xong API mới có thể bắt đầu integrate, nếu bạn có thể mock những API sẽ được trả về dựa trên contract đã thống nhất, thì gần như là không còn quá nhiều việc phải làm khi API làm xong.

  3 bước tối ưu hiệu năng React App bằng các API mới của React
  API là gì? Tại sao API được sử dụng nhiều hiện nay?

Làm như thế nào

Để mock API, kể thể dùng nhiều cách như JSON Servermountebank, hôm nay mình hướng dẫn dùng Mirage mình mới biết, kết hợp với Vue nhé, React cũng tương tự thôi.

  1. Cài đặt vào devDependencies
npm i miragejs -D
  1. Mình chọn tổ chức thư mục theo kiểu này, bạn có thể để nó ở chỗ khác thì tùy ý
/
├── public
├── src
│   ├── api
│   │   └── mock
│   │       ├── fixtures
│   │       │   └── get-tasks.js
│   │       └── index.js
│   └── main.js
├── package.json
└── package-lock.json
  1. Tạo mock server
// api/mock/index.js
import { Server } from 'miragejs';

export default function ({ environment = 'development' } = {}) {
  return new Server({
    environment,
    routes() {
      // chút thêm routes ở đây
    },
  });
}
  1. Mở file dùng để bootstrap app của chúng ta, đang dùng Vue nó sẽ là src/main.js (src/index.js nếu bạn dùng với React)
import createServer from './api/mock';

// chỉ tạo fake server trong lúc chạy dev mode
if (process.env.NODE_ENV === 'development') {
    createServer();
}

Ví dụ bạn gọi API trong code như thế này

await axios.get('/api/tasks');

Chúng ta sẽ cập nhập lại file api/mock/index.js, bổ sung route /api/tasks cho mock server

// api/mock/index.js

export default function ({ environment = 'development' } = {}) {
    // ...
    routes() {
      this.get('/api/tasks', () => ({
        tasks: [
          { id: 1, text: "Feed the cat" },
          { id: 2, text: "Wash the dishes" },
          //...
        ],
      }))
    },
  });
}

Tương tự để mock các HTTP method khác

this.get('/tasks', (schema, request) => { ... });
this.post('/tasks', (schema, request) => { ... });
this.patch('/tasks/:id', (schema, request) => { ... });
this.put('/tasks/:id', (schema, request) => { ... });
this.del('/tasks/:id', (schema, request) => { ... });
this.options('/tasks', (schema, request) => { ... });

Nếu mọi thứ êm đẹp bạn sẽ được thông báo trên cửa sổ console

Mock API bằng Mirage JS

Thêm nội dung động

Bạn có thể dùng fakerjs để chèn thêm dữ liệu một cách ngẫu nhiên.

Để có dữ liệu init cho fake server, chúng ta sẽ sử dụng seeds()

export default function ({ environment = 'development' } = {}) {
    seeds(server) {
        server.db.loadData({
            tasks: [
                { id: 1, text: "Feed the cat" },
                { id: 2, text: "Wash the dishes" },
            ],
        })
    },
    routes() {
        this.get('/api/tasks', (schema) => {
            return schema.db.tasks;
        }),
        this.post('/api/tasks', (schema, request) => {
          // nhận data được gửi từ post
          const task = JSON.parse(request.requestBody).data;
          return schema.db.tasks.insert(task);
        })
        ...
    },
  });
}

Thêm route động

Route động là gì, ví dụ như bạn dùng phương thức delete hay update bằng một route như thế này

DELETE: /api/tasks/8lVzv5lv2n6Mu912x19UdKDC08
PUT: /api/tasks/8lVzv5lv2n6Mu912x19UdKDC08
// api/mock/index.js
...
this.delete('/api/tasks/:id', (schema, request) => {
  	// id từ url
    const id = request.params.id;
    return schema.db.tasks.remove(id);
})
...

Nếu bạn để ý, tất cả đều bắt đầu bằng apinamespace sinh ra là để phục vụ đối tượng lười biếng như chúng ta

routes() {
    // bọn dưới sẽ bắt đầu bằng /api hết
    this.namespace = '/api';

    this.get('/tasks', () => { ... })
    this.delete('/tasks/:id', () => { ... })
    this.post('/tasks', () => { ... })
}

Giả lập những route chỉ định

Nếu như bạn đã có một số API, một số BE đang implement, tất nhiên chúng ta chỉ mock những API chưa làm, còn cái nào làm rồi thì cứ xài cái thật luôn

routes() {
    // chỉ giả lập GET /task
    this.get('/task', () => { ... });
    
    // còn lại dùng hàng thật
    this.passthrough();
}

Nhưng đa phần API thật sẽ nằm đâu đó chứ không phải localhost:3000, thêm đoạn sau

routes() {
    // api thực nằm ở đây
    this.urlPrefix = 'https://devenv.ourapp.example';
    
    // chỉ giả lập GET /task
    this.get('/task', () => { ... });
    
    // còn lại dùng hàng thật
    this.passthrough();
}

Lúc này tất cả API đều sẽ gọi lên https://devenv.ourapp.example, duy chỉ gặp thằng https://devenv.ourapp.example/task`, mirage sẽ intercept và đưa hàng giả vào.

Kết

Sử dụng cũng được vài cái thư viện làm mock API, MirageJS là thằng mình thấy ưng nhất, không quá phức tạp, giải quyết được những vấn đề rất căn cơ của FE.

Mirage JS còn khá nhiều chiêu trò thú vị chờ bạn khám phá trên tài liệu chính thức của nó, nếu thấy hay đừng quên nhất like và contribute cho dự án trên Github

Happy coding 🎉🙌

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

Hỡi mấy anh developer – Bớt sử dụng if else – source đẹp hẳn ra

Hỡi mấy anh developer – Bớt sử dụng if else – source đẹp hẳn ra

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

Như cái tiêu đề sock hàng, bài viết này chủ yếu nói về việc hạn chế sử dụng if else nhiều nhất có thể.

Viết nhiều if else là phù hợp cho những người mới bắt đầu. Còn khi đã đạt tới “trình” cao hơn, hãy luôn tìm mọi cách để loại bỏ đi các đoạn if else không cần thiết trong souce.

BẰNG CÁCH NÀO?. Đây, một vài cách có thể áp dụng!

  CSS Specificity là gì vậy?
  Giải thích React Component Lifecycle

1. Chúng ta có return

Sử dụng if else nhiều lần gần như là vấn đề mà bất kì Junior Developer nào cũng gặp phải. Cùng xem xét ví dụ dưới đây:

Java

public void checkConditionSomething(int input) {
if (input > 10) {
// Do something in case greater than 10
} else {
// Do some something
}
}

Code như này thường là có code của Junior, suy nghĩ đơn giản. Nếu này thì làm gì, ngược lại thì làm gì. Viết kiểu này tốt cho người mới bắt đầu vì dễ hiểu, dễ áp dụng.

Tuy nhiên, nên nhớ là ta vẫn còn return, một return sẽ đổi được một else. Nhìn còn professional khi viết các function nhỏ.

Java

public void checkConditionSomething(int input) {
if (input > 10) {
return
}
// Do something like else
}

Trường hợp logic thực thi ở if và else chỉ là single (gán, so sánh, return giá trị). Cách viết chuẩn mực, gọn gàng.

Java

public boolean checkConditionSomething(int input) {
// Khỏi cần if else source vẫn đẹp như thường
return input > 10 ? true : false;
}

Còn viết function sao cho tốt thì có thể tham khảo bài viết về function – viết sao cho tốt tại Kieblog

2. Return thay cho sử dụng if else thừa

Cũng là một cách khác, tuy nhiên thay vì sử dụng if else với else cuối cùng, ta có thể return ngay lập tức giá trị đó.

Java

public String getStringValue(int input) {
String value = "";
// Một đoạn if else dài loằng ngoằng
if (input == 0) {
value = "Kie";
} else if (input == 1) {
value = "blog";
} else {
value = "Kieblog";
}
return value;
}

If else kiểu này thì thật sự là thảm họa. Tuy nhiên, lúc ngồi nghĩ về logic viết như thế này có thể chấp nhận được. Nhưng sau đó thì sao?.

Khi maintainance, có thể bỏ bớt else bằng cách return giá trị default.

Java

public String getStringValue(int input) {
// Không còn else, source đẹp, dễ hiểu
// Không mất công decleare variable
if (input == 0) return "Kie";
if (input == 1) return "blog";
return "Kieblog";
}

3. Bỏ if else dùng dictionary

Ngoài sử dụng if else ta còn có thể sử dụng Dictionary để thay thế cho các block if else.

Java

public String getStringValue(int input) {
String value = "";
// Một đoạn if else dài loằng ngoằng
if (input == 0) {
value = "Kie";
} else if (input == 1) {
value = "blog";
} else {
value = "Kieblog";
}
return value;
}

Có thể sử dụng Dictionary như sau:

Java

public String getStringValue(int input) {
// Dùng dictionary cũng là một cách, đẹp source ra hẳn
var operations = new Dictionary<string, Action>();
operations[0] = () => { //Do something }
operations[1] = () => { // Do something }
}

Sử dụng if else quá nhiều lần không những không làm rõ được nội dung đoạn source. Ngược lại còn làm rối tung rối mù lên. Tuy thuận tiện khi viết source logic lần đầu, nhưng nên thay đổi để bỏ bớt khi refactor source lần sau.

Viết cẩn thận chứ không em út sau đọc nó chửi sml ra.

4. Tham khảo

  • How to replace many if statements in Java
  • Refactoring If-else statement
  • Câu lệnh rẽ nhánh (if else) trong Java

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

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

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

3 cách xóa phần tử bị duplicate trong mảng

3 cách xóa phần tử bị duplicate trong mảng

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

Nếu phần tử trong mảng chỉ là kiểu primitive thì rất đơn giản nếu muốn xóa tất cả phần tự bị trùng

  5 cách chia một mảng lớn thành nhiều mảng nhỏ trong Javascript
  Bạn hoàn toàn có thể xây dựng cho mình một Mạng Xã Hội & Kinh Doanh trên đó
const values = ['a','b','c','a']

const uniqueValues = [...new Set(values)];

Còn nếu phần tử trong mảng là object thì ta làm sao?

const members = [
  {
    first: 'Jane',
    last: 'Bond',
    id: '10yejma',
  },
  {
    first: 'Lars',
    last: 'Croft',
    id: '1hhs0k2',
  },
  {
    first: 'Jane',
    last: 'Bond',
    id: '1y15hhu',
  },
];

Cách 1: tạo mảng mới ko chứa phần tử bị trùng

function containsMember(memberArray, member) {
    return memberArray.find(m => m.first === member.first && m.last === member.last)
}

const uniqueValues = [];

for	(const m of members) {
    if (!containsMember(uniqueValues, m)) {
        uniqueValues.push(m);
    }
}

Cách 2: dùng filter()

function getIndexOfMember(memberArray, member) {
    return memberArray.findIndex(m => m.first === member.first && m.last === member.last)
}

const uniqueValues = members.filter((m, index, ms) => getIndexOfMember(ms, m) === index);

Cách 3: sử dụng Map

const uniqueKeyToMember = new Map(members.map(m => [m.first+'\t'+m.last, m]));

const uniqueMembers = [...uniqueKeyToMember.values()]; 

Eliminating duplicate objects: three approaches

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

Bắt đầu với nghề ITBA

bắt đầu với nghề ITBA

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

Theo IIBA: Business Analyst là người kết nối giữa các bên liên quan để gợi ý, phân tích, giao tiếp và làm rõ các yêu cầu đối với các thay đổi đối với quy trình kinh doanh, chính sách và hệ thống thông tin

Nghề BA nói chung hay IT BA là một ngành nghề ngày càng phổ biến ở nước ta hiện nay. Trước đây BA chỉ thường ở các công ty làm việc tài chính, ngân hàng nhưng hiện nay thì phổ biến ở nhiều lĩnh vực. Mỗi BA thường sẽ đi sâu và làm việc chủ yếu với một domain nhất định, tuy nhiên cũng có những cách chung để tiếp cận với những domain khác nhau.

  "Ngành IT này học rất dễ, tài liệu ko bao giờ thiếu. Quan trọng là phải có đam mê và chịu cày"
  10 dự đoán hàng đầu của ngành IT trên toàn thế giới

Mình xin chia sẻ những điều mà mình rút ra được trong quãng thời gian xin việc và làm IT BA trong vòng 3 năm.

Những kỹ năng cần thiết của một IT BA

1. Kỹ năng giao tiếp: BA là người phải giao tiếp trực tiếp với khách hàng để lấy yêu cầu, trao đổi dev, test để đưa ra solution tốt nhất. Vì thế người làm BA phải là một người giao tiếp tốt. Họ có thể tổ chức điều hành thành công các buổi họp, biết cách đặt vấn đề, biết lắng nghe và tiếp nhận các ý kiến trong buổi họp. Ngày nay, việc giao tiếp không phải lúc nào cũng là gặp mặt trực tiếp. Vì vậy, kỹ năng giao tiếp tốt trong các buổi họp trực tuyến cũng rất quan trọng.

2. Kỹ năng sử dụng SQL: Đây là kỹ năng quan trọng của một IT BA. Vì họ là người hiểu rõ về các bảng và cách lấy dữ liệu từ các bảng trong database.

3. Kỹ năng phân tích, phản biện: BA có trách nhiệm đánh giá, lựa chọn giải pháp trước khi làm việc với các thành viên trong nhóm. Trong quá trình xác định các vấn đề cần giải quyết của dự án, BA phải thu thập yêu cầu của khách hàng nhưng đồng thời cũng phải phân tích những yêu cầu này một cách cẩn thận và chi tiết cho đến khi BA chắc chắn hiểu được những yêu cầu, mong muốn thực sự của khách hàng. Đây là lý do tại sao kỹ năng tư duy phản biện và kỹ năng phân tích, đánh giá là rất quan trọng với một người BA mới.

5. Kỹ năng mô hình hóa vấn đề bằng biểu đồ: Phần lớn dev đều lười mở tài liệu ra đọc vì thế khi làm việc họ mong muốn có những biểu đồ rõ ràng thì sẽ đưa đến họ hơn. Một bức hình đáng giá hơn cả ngàn chữ – Các mô hình sẽ giúp người đọc dễ dàng nắm bắt ý tưởng hơn. Một vài mô hình điển hình: Use cases diagram, sequence diagram, Workflow diagrams, wireframe prototypes…. Với mỗi kĩ năng phân tích, tương ứng sẽ có một loại mô hình mà BA cần phải tạo. Đặc biệt, người làm BA nên có kĩ năng mô hình hóa lại thông tin mọi lúc, mọi nơi dù là sử dụng các mô hình chuẩn hay chỉ đơn giản là một mô hình nguệch ngoạc trên giấy.

6. Kỹ năng làm tài liệu: Khi viết tài liệu thì yêu cầu đầu tiên là viết rõ ràng và chính xác và quan trọng hơn hết là viết cho người đọc hiểu chứ không phải cho mình hiểu! Nếu bạn là một BA mới vào nghề, bạn sẽ chưa biết cách tạo ra các tài liệu đặc tả mà người làm BA phải tạo. Tuy nhiên, bạn vẫn có thể bắt đầu viết những tài liệu nếu như bạn có sẵn kĩ năng viết tốt.

Những vấn đề thường gặp khi bắt đầu đi xin việc

Bắt đầu với nghề ITBA

Đối với ngành BA thường các công ty tuyển dụng hay yêu cầu có kinh nghiệm làm việc 1 năm trở lên, tuy nhiên hiện nay cũng nhiều công ty tuyển Intern hoặc Fresher đây chính là cơ hội với người mới. Tuy nhiên, ở các công ty trong lĩnh vực IT thì mọi người hay chuyển từ dev hoặc test sang làm BA vì thế các bạn khi còn là sinh viên có thể xin thực tập dev, test ở công ty sau đó xin chuyển sang làm BA, đây cũng là một cách để tiếp cận dễ dàng hơn. Song như mình nói ở trên hiện nay thì có rất nhiều công ty tuyển Fresher hoặc Junior không yêu cầu kinh nghiệm vì thế bạn hoàn toàn có thể tự tìm hiểu và đi phỏng vấn.

  • Những câu hỏi thường được hỏi khi phỏng vấn
  1. Tại sao bạn lại mong muốn chuyển sang làm BA? Trước khi chuyển sang làm BA thì mình dev vì thế lần nào đi phỏng vấn cũng nhận được câu hỏi này. Vì bản thân mình sau một thời gian làm dev thì thấy không phù hợp với nhu cầu phát triển của bản thân, khi đi học thì mình cũng thích giao tiếp với mọi người nên khi đổi ngành mình đã chọn làm BA.
  2. Bạn hiểu BA là làm những công việc gì? Hầu hết trong trường học mọi người đều không được giới thiệu BA là gì, làm những công việc gì tuy nhiên trước khi chuyển sang công việc mới thì mọi người nên tham gia khóa học hoặc tìm hiểu thông tin trên mạng. Nội dung chi tiết BA sẽ làm những gì thì mình sẽ giới thiệu ở bài sau.
  3. Điểm mạnh, điểm yếu của bạn khi làm BA là gì? Với mình điểm mạnh của mình là mình đã từng làm dev nên có hiểu biết cơ bản về kiến trúc của dự án công nghệ thông tin và các kỹ năng cơ bản như mô hình hóa yêu cầu, sql. Điểm yếu của mình thì nhiều khi hay đưa vấn đề của dev khi nói chuyện với khách hàng.
  4. Một số câu hỏi liên quan đến SQL? Bạn nên nắm được một số câu lệnh SQL đơn giản như Select, Join, Group by.
  5. Một số tình huống đơn giản và đưa ra cách giải quyết vấn đề? Ví dụ: Nếu khách hàng đưa bạn yêu cầu mới mà bạn chưa từng biết đến thì bạn phải làm thế nào?

Những công việc của một IT BA

  1. Nhận yêu cầu từ khách hàng hoặc quản lý cấp trên, đôi khi ở các công ty làm sản phẩm thì yêu cầu sẽ đi từ đội kinh doanh hoặc từ nhu cầu thị trường
  2. Phân tích, làm rõ yêu cầu. Đưa ra list function.
  3. Làm các tài liệu liên quan:
  • Tài liệu Architecture: Tài liệu mô tả luồng thao tác người dùng, luồng hoạt động của hệ thống, cấu trúc cơ bản của hệ thống, các thành phần trong hệ thống, tương tác giữa các thành phần trong hệ thống
  • Tài liệu SRS hay basic design: Tài liệu mô tả chi tiết các chức năng, giao diện của từng chức năng
  • Tài liệu test point: Các testcase cơ bản, đặc thù liên quan đến giao diện từ phía người dùng
  • Thiết kế mô tả database: Database hệ thống, mô tả chức năng của các bảng các trường đặc biệt.
  1. Transfer logic cho dev, test.
  2. Check lại hệ thống trước khi đi đến khách hàng
  3. Training, hướng dẫn khách hàng sử dụng hệ thống

Trên đây là khái quát các công việc của một IT BA dưới cái nhìn chủ quan của mình. Các bạn đọc có ý kiến khác vui lòng comment phía dưới. Xin cảm ơn.

Bài viết gốc được đăng tải tại kinhnghiemlaptrinh.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

Xây dựng crawler siêu đơn giản với Java

Xây dựng crawler siêu đơn giản với Java

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

Giới thiệu

Crawler là một công cụ giúp thu thập dữ liệu, thông tin từ các trang web khác nhau. Một trong những ví dụ về crawler mà chúng ta gặp hằng ngày là Google. Google là một hệ thống có nhiều máy chủ có thể crawling rất nhiều trang web trên Internet, từ đó chúng ta có thể tìm kiếm nội dung những trang web mà chúng ta cần dựa vào từ khoá cụ thể. Hoặc là những trang web so sánh giá cả từ nhiều nguồn khác nhau (websosanh.vn), trang tin báo tổng hợp (baomoi.com) và nhiều ví dụ khác mà mình không thể liệt kê hết ở đây.

Chúng ta có thể tự viết một crawler đơn giản nhằm thu gom một số dữ liệu cơ bản nào đó. Khi hướng dẫn học viên học module 2 (Advance Programming with Java) tại CodeGym, mình thường giao bài tập xây dựng công cụ crawler này. Ví dụ thu thập giá bất động sản trên các trang rao vặt hoặc giá sản phẩm trên các trang thương mại điện tử. Qua bài viết này, mình sẽ hướng dẫn lại các bạn làm bài tập này với ngôn ngữ lập trình Java.

Tuyển dụng Java lương cao mới nhất

Một số yêu cầu cơ bản để thực hiện bài tập này:

  • Nắm vững cú pháp ngôn ngữ lập trình Java
  • Sử dụng được ngôn ngữ đánh dấu HTML
  • Sử dụng được biểu thức chính quy (regular expression) — còn được gọi là regex
  • Một ít hiểu biết về HTTP (Giao thức được sử dụng để truy cập các trang web qua Internet)
  • Hiểu cơ bản phương pháp lập trình hướng đối tượng
  • Hiểu cơ bản về design pattern

Ghi chú: Trên thực tế, có nhiều thư viện hỗ trợ chúng ta làm crawler hiệu quả hơn cách làm trong bài này. Với mục đích học là chính, mình sẽ không sử dụng các thư viện đấy mà sẽ tự xây dựng lấy, các bạn nhé!

Thiết kế chương trình

Chúng ta sẽ xây dựng một công cụ có thể thu thập được tin tức bất động sản đang rao (bao gồm bán và cho thuê) tại các website sau:

  • https://batdongsan.com.vn/
  • https://batdongsan24h.com.vn/
  • https://nhadat24h.net/
  • https://diendanbatdongsan.vn/

Mô tả dữ liệu

Khai báo class có tên là ClassifiedAd để mô tả thông tin thu thập được từ các trang web. Bao gồm: tiêu đề, loại tin rao, diện tích, giá, mô tả chi tiết, hình ảnh (link).

Sau khi khảo sát nội dung các trang web, chúng ta thấy rằng:

  • Các tin có thể hiển thị giá tổng (tính trên toàn bộ diện tích) hoặc giá theo mét vuông. Vì vậy cần khai báo những class sau để mô tả loại giá được hiển thị: enum TypePriceclass Price.
  • Đơn vị tiền có thể là “triệu đồng” hoặc “tỷ đồng”. Vì vậy cần thuộc tính unit tương ứng trong class Price. Giá trị được liệt kê trong enum Unit để xác định đơn vị tiền tệ.
  • Các tin rao được phân loại thành: bán căn hộ, bán nhà đất, bán biệt thự, cho thuê,… enum TypeAd được khai báo cho mục đích này.
enum TypePrice {
    PRICE_PER_M2,   // loại giá dựa trên m2
    TOTAL_PRICE     // giá toàn bộ
}
enum Unit {
    MILLION_VND,
    BILLION_VND,
}
class Price {
    private Float price;
    private TypePrice typePrice;
		private Unit unit;
}
enum TypeAd {
		...,
    SELL,
    RENTAL,
    OTHERS
}
class ClassifiedAd {
    private String title;       // tiêu đề
    private TypeAd typeAd;      // loại tin
    private Price price;        // giá
    private Float acreage;      // diện tích
    private String description; // mô tả
}
  10 Java Web Framework tốt nhất
  10 lý do cho thấy tại sao bạn nên theo học ngôn ngữ lập trình Java

Thiết kế tổng quan

Qua khảo sát các trang web mà cần thu thập tin, chúng ta có thể xác định thứ tự các bước để thu thập tin như sau:

  1. Truy cập trang chủ, liệt kê danh sách những danh mục tin (ví dụ: chung cư, nhà đất, biệt thự,…)
  2. Truy cập các danh mục tin để liệt kê các tin đang rao
  3. Truy cập trang chi tiết của từng tin để lấy các thông tin chi tiết

Chúng ta sẽ áp dụng pattern Template Method để chuyển các bước trên thành một dãy các bước xử lý chung cho mỗi trang web.

public abstract class Crawler {
// bước 1
    abstract Iterable<Subpage> inspectHomepage();
		
// bước 2
    abstract Iterable<DetailPage> inspectSubpage(Subpage subpage);
		
// bước 3
    abstract ClassifiedAd inspectDetailPage(DetailPage detailPage);
// Đây là thao tác chung cho tất cả các trang web mà chúng ta muốn thu thập tin
    Iterable<ClassifiedAd> inspect() {
        List<ClassifiedAd> classifiedAds = new ArrayList<>();
        Iterable<Subpage> subpages = inspectHomepage();
        for (Subpage subpage: subpages) {
            Iterable<DetailPage> detailPages = inspectSubpage(subpage);
            for (DetailPage detailPage: detailPages) {
                ClassifiedAd classifiedAd = inspectDetailPage(detailPage);
                classifiedAds.add(classifiedAd);
            }
        }
        return classifiedAds;
    }
}

Với mỗi trang web cụ thể, chúng ta có một cách thu thập khác nhau (vì giao diện mỗi trang khác nhau). Trong tương lai, chúng ta có thể bổ sung những trang web khác hoặc thay đổi cách thức thu thập. Vì thế chúng ta sẽ xây dựng các class phục vụ việc crawle cho từng trang web cụ thể theo thiết kế như sau:

Sơ đồ lớp (class diagram) chương trình Crawler

Ở thiết kế trên, chúng ta áp dụng kiến thức về abstract class trong lập trình hướng đối tượng nhằm đảm bảo có thể dễ dàng mở rộng các trang web muốn thu thập. Khi cần bổ sung trang mới, chúng ta có thể implement thêm Crawler mà không phải sửa đổi ở khung thiết kế và luồng thực thi của chương trình. Cuối cùng là class MySimpleCrawler chứa đoạn mã khởi động chương trình.

Bây giờ, chúng ta viết mã kiểm tra xem ý tưởng thiết kế trên có thể thực hiện được chưa nhé! Tính năng ban đầu sẽ là khởi động chương trình và lấy những tin rao ở các trang batdongsan.com.vn.

Ghi chú: Ở công cụ siêu đơn giản này, chúng ta chưa tính đến việc làm thế nào để tối ưu thời gian chạy, lấy nhiều tin ở các trang tiếp theo, lên lịch chạy để luôn cập nhật được tin mới nhất, hoặc thậm chí là cấu hình thời gian ngắt quãng giữa các lần thu thập (để tránh trường hợp một số trang không cho phép tạo request liên tục trong khoảng thời gian nhất định nào đó).

Start coding!

1. Xác định các nội dung cần thu thập

Để lấy được nội dung trang web, chúng ta có thể sử dụng một tính năng tạo HTTP request đơn giản mà Java cung cấp là class URL.

Để tạo một request đến trang web cần lấy nội dung, chúng ta sử dụng hàm dưới đây:

private static String getContentFrom(String link) throws IOException {
        // Gởi HTTP request và nhận về kết quả là chuỗi các thẻ HTML
        URL url = new URL(link);
        Scanner scanner = new Scanner(new InputStreamReader(url.openStream()));
        scanner.useDelimiter("\\\\Z");
        String content = scanner.next();
        scanner.close();
        // xoá các ký tự ngắt dòng (xuống dòng)
        content = content.replaceAll("\\\\R", "");
        return content;
    }
</pre

Khi request thành công, các trang web thường trả về các thẻ HTML. Nếu nơi nhận là trình duyệt thì các thẻ HTML này sẽ được dựng hình (render) thành giao diện của trang web. Còn công cụ crawler của chúng ta chỉ xem đấy là các chuỗi ký tự. Việc chúng ta cần làm là tìm những vị trí chứa thông tin cần thiết bên trong chuỗi ấy. Biểu thức chính quy (regex) có thể được áp dụng trong trường hợp này.

Như vậy, chúng ta cần làm hai bước sau để lấy được thông tin trong trang web:

  • Bước 1: Xác định vị trí thông tin cần lấy trong chuỗi HTML để tìm được quy tắc đánh dấu
  • Bước 2: Dựa vào quy tắc đánh dấu trên, chúng ta xác định biểu thức chính quy phù hợp để lọc được chuỗi thông tin cần thiết

Để đơn giản hoá Bước 1 — Tìm vị trí các thông tin cần thiết trong chuỗi HTML trả về, chúng ta có thể sử dụng chức năng Inspect (trong bộ Developer Tools) của trình duyệt Google Chrome hoặc Firefox để tra đến vị trí mã nguồn thông qua giao diện trực quan.

Dưới đây là phần minh hoạ các bước trên cho việc liệt kê danh sách những danh mục tin ở trang chủ của trang web batdongsan.com.vn (Như đã trình bày Bước 1 trong mục Thiết kế tổng quan).

1.1. Hướng dẫn bước 1

  • Truy cập trang web batdongsan.com.vn trên trình duyệt
  • Mở chức năng Inspect với phím tắt Option + CMD + I (hệ điều hành MacOS) hoặc Ctrl + Shift + P (hệ điều hành Windows)
  • Di chuyển chuột đến mục Nhà đất bán > Bán căn hộ chung cư trên thanh định hướng (menu) > Bấm chuột phải > Chọn Inspect.

Rê chuột đến mục Nhà đất bán > Bán căn hộ chung cư trên thanh định hướng (menu), click chuột phải, chọn Inspect.

  • Qua nội dung hiển thị trên tab Element, chúng ta có thể thấy mã HTML của những thẻ đánh dấu mục Bán căn hộ chung cư như bên dưới:

Qua nội dung hiển thị trên tab Element, chúng ta có thể thấy mã HTML của những thẻ đánh dấu mục Bán căn hộ chung cư như trên.

Như vậy, chúng ta xác định được mã đánh dấu các đường link của các danh mục tin trên trang web này là thẻ <a> nằm trong thẻ <li> có class là lv1.

1.2. Hướng dẫn bước 2

Qua bước 1, chúng ta xác định được rằng, để lấy được đường link của danh mục con Bán căn hộ chung cư thì phải lấy thuộc tính href của thẻ <a> nằm trong <li class="lv1">.

Vậy regex có thể dùng ở đây là:

 "<li class='lv1'><a href='(.*?)' class='haslink '>"

Giá trị của thông tin mà chúng ta muốn tìm là đường link nằm giữa <li class='lv1'><a href=' và ' class='haslink '> được đại diện bằng các kí tự (.*?).

Bạn có thể kiểm tra kết quả tìm kiếm dựa trên regex trên bằng một chương trình demo nhỏ với những dòng mã sau:

public class DemoUsingURL {
    private static String getContentFrom(String link) throws IOException {
        ...
    }
    public static void main(String[] args) throws IOException {
        String content = getContentFrom("<https://batdongsan.com.vn>");
        // Regex
        Pattern p = Pattern.compile("<li class='lv1'><a href='(.*?)' class='haslink '>");
        Matcher m = p.matcher(content);
        while (m.find()) {
            System.out.println(m.group(1));
        }
    }
}

Kết quả của đoạn code trên như sau:

/ban-can-ho-chung-cu
/ban-nha-rieng
/ban-nha-biet-thu-lien-ke
/ban-nha-mat-pho
/ban-dat-nen-du-an
...
...
/phong-thuy-van-phong
/tin-tuc-phong-thuy-theo-tuoi
/nha-moi-gioi
/doanh-nghiep

Đây là những đường link con, có thể kết hợp với chuỗi https://batdongsan.com.vn để tạo ra đường link dẫn tới nội dung các danh mục tin được rao.

Ở kết quả trên, chúng ta thấy có một số đường link không phù hợp. Vì đó là những đường link mà chúng ta không muốn thu thập nội dung. Ví dụ: /phong-thuy-van-phong/tin-tuc-phong-thuy-theo-tuoi/nha-moi-gioi,… Chúng ta sẽ tìm cách loại bỏ những kết quả không mong đợi này.

Xem xét lại mã HTML của trang web, chúng ta sẽ phát hiện ra các thẻ <li class='lv1'> chứa các thông tin cần thiết này nằm trong 2 nội dung sau:

Nhà đất bán

<li class='lv0'><a href="/nha-dat-ban" class="haslink ">Nhà đất bán</a>
...nội dung các danh mục con của mục Nhà đất bán ở đây
</li>

Nhà đất cho thuê

<li class='lv0'><a href="/nha-dat-cho-thue" class="haslink ">Nhà đất cho thuê</a>
...nội dung các danh mục con của mục Nhà đất cho thuê ở đây
</li>

Đoạn code trên cần sửa lại như dưới đây để loại ra những link không cần thiết:

public class DemoUsingURL {
    private static String getContentFrom(String link) throws IOException {
        ...
    }
    private static List<String> getLinksFromMenu(String content, String menuPattern) {
        // Regex
        List<String> links = new ArrayList<>();
        Pattern p = Pattern.compile(menuPattern);
        Matcher m = p.matcher(content);
        while (m.find()) {
            Pattern p2 = Pattern.compile("<li class='lv1'><a href='(.*?)' class='haslink '>");
            Matcher m2 = p2.matcher(m.group(1));
            while (m2.find()) links.add(m2.group(1));
        }
        return links;
    }
    public static void main(String[] args) throws IOException {
        String content = getContentFrom("<https://batdongsan.com.vn>");
        String sellMenuPattern = "<li class='lv0'><a href='/nha-dat-ban' class='haslink '>Nhà đất bán</a><ul>(.*?)</ul>";
        List<String> sellLinks = getLinksFromMenu(content, sellMenuPattern);
        String rentalMenuPattern = "<li class='lv0'><a href='/nha-dat-cho-thue' class='haslink '>Nhà đất cho thuê</a><ul>(.*?)</ul>";
        List<String> rentalLinks = getLinksFromMenu(content, rentalMenuPattern);
        System.out.println(sellLinks);
        System.out.println(rentalLinks);
    }
}

Ở đoạn code trên, mình tách phần lấy nội dung từ đường dẫn trang web thành hàm getContentFrom, và một hàm tách link từ nội dung có tên là getLinksFromMenu. Hàm main sử dụng hai hàm được khai báo ở trên để lấy các đường link nằm trong mục Nhà đất bán và Nhà đất cho thuê.

1.3. Thực hành

Bây giờ, các bạn có thể tự thực hành với hướng dẫn hai bước trên để xác định những thông tin còn lại.

Nếu cần có kết quả ngay thì bạn có thể tham khảo mã nguồn mình cung cấp ở cuối bài viết này! 🙂

1.4. Tổng hợp các regex tìm được

Dưới đây các regex đã tìm được với trang batdongsan.com.vn để các bạn tham khảo:

  1. Link các danh mục tin
  2. Link đến nội dung chi tiết
  3. Thông tin cụ thể (như tiêu đề, giá, diện tích,…) trong tin chi tiết

1.4.1. Link các danh mục tin

Tìm các link bên trong mục “Nhà đất bán” và “Nhà đất cho thuê”:

Pattern p1 = Pattern.compile("<li class='lv0'><a href='/nha-dat-ban' class='haslink '>Nhà đất bán</a><ul>(.*?)</ul>");
Pattern p2 = Pattern.compile("<li class='lv0'><a href='/nha-dat-cho-thue' class='haslink '>Nhà đất cho thuê</a><ul>(.*?)</ul>");

Sau đó, tìm các link danh mục thuộc “Nhà đất bán” và “Nhà đất cho thuê” để loại các link không cần thiết:

Pattern pLink = Pattern.compile("<li class='lv1'><a href='(.*?)' class='haslink '>");

1.4.2. Link đến nội dung chi tiết

 Pattern p = Pattern.compile("<div class='p-title'><h3><a href='(.*?)' title");

1.4.3. Thông tin cụ thể trong tin chi tiết

<span id="48e5" class="ir gx ap ce in b ei is it r iu" data-selectable-paragraph="">String title = "<h1 itemprop=\\"name\\">(.*?)</h1>";
String price = "<span class=\\"gia-title mar-right-15\\"><b>Giá:</b><strong>(.*?)</strong>";</span><span id="e97c" class="ir gx ap ce in b ei iv iw ix iy iz it r iu" data-selectable-paragraph="">Pattern p = Pattern.compile(title + ".*" + price);</span>

2. Viết mã crawler cho từng trang web cụ thể

Xác định được các regex pattern để lấy những thông tin cần thiết ở trên là chúng ta đã đi được 50% chặng đường. Việc còn lại là kết hợp các regex trên để viết mã crawler cụ thể cho từng trang web theo thiết kế được trình bày trong mục Thiết kế tổng quan.

Các class dành cho trang cụ thể sẽ implement những phương thức abstract đã định nghĩa trong Crawler:

    // bước 1
    abstract Iterable<Subpage> inspectHomepage();
		
    // bước 2
    abstract Iterable<DetailPage> inspectSubpage(Subpage subpage);
		
    // bước 3
    abstract ClassifiedAd inspectDetailPage(DetailPage detailPage);

inspectHomepage() sẽ sử dụng các regex như minh hoạ trong mục Hướng dẫn bước 1.

inspectSubpage trả về danh sách link các trang chi tiết.

inspectDetailPage trả về thông tin cụ thể từ trang chi tiết.

Cải tiến

Như đã trình bày ở trên, đây là một công cụ “siêu đơn giản”. Vì thế sẽ thiếu nhiều tính năng để crawler thực sự hữu ích trên thực tế như tối ưu thời gian chạy, lên lịch chạy để luôn cập nhật được tin mới nhất, lưu vào kho dữ liệu phù hợp phục vụ tra cứu hoặc tính toán/so sánh…

Mình sẽ đưa ra một số gợi ý để các bạn có thể tiếp tục tìm hiểu và cải tiến công cụ này nhé!

  1. Sử dụng Thread để tối ưu thời gian chạy, giảm thời gian đợi giữa các lần request nội dung từng trang web. Vì mỗi trang được xử lý độc lập, việc đợi kết quả của request này sẽ không ảnh hưởng đến kết quả của các request còn lại.
  2. Sử dụng Crob Job để lên lịch chạy hằng ngày hoặc một khung thời gian cố định (ví dụ: 10 phút 1 lần). Hiện tại, các thao tác phải được kích hoạt thủ công. Việc này sẽ không giúp hệ thống có được dữ liệu mới nhất.
  3. Sử dụng một hệ CSDL cụ thể để gom dữ liệu thu thập được. Hệ CSDL sẽ giúp chúng ta có thể xử lý và đưa ra một số thông tin hữu ích. Ví dụ: so sánh giá thị trường với từng khu vực cụ thể, hoặc tìm giá tốt nhất được rao trên các trang theo nhu cầu của người dùng.

Author: Đặng Huy Hòa

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

CSS Specificity là gì vậy?

CSS Specificity là gì vậy?

Bài viết được sự cho phép của tác giả Phúc Lương

Mở bài

Chào các bạn, hôm nay mình sẽ tiếp tục series về CSS cơ bản. Bài viết lần này như tiêu đề đã ghi rõ, mình sẽ giới thiệu và phân tích về Specificity trong CSS. Đây là phần kiến thức quan trọng bậc nhất (không nhất thì nhì :D) nhưng lại không quá phức tạp, mình sẽ cố gắng trình bày những thứ đơn giản mà chúng ta hay sử dụng hàng ngày thôi. Nếu các bạn thấy có thiếu sót hay phản hồi gì thì vui lòng cho mình biết ở comment bên dưới nhé.

  5 điều phiền toái nhất của CSS
  11 công cụ hữu ích để kiểm tra và tối ưu hóa các file CSS

Đặt vấn đề

Trong một buổi phỏng vấn khi còn là mid-level developer, mình từng được đặt một câu hỏi cơ bản mang tính lý thuyết cao nhưng mình không trả lời được, mình xin viết lại ra đây (không chính xác hoàn toàn nhưng bản chất câu hỏi không đổi)

<html>
  <head>
    <style>
      body h1 { color: green; }
      html h1 { color: purple; }
    </style>
  </head>

  <body>
    <h1>text</h1>
  </body>
</html>

Theo bạn thì thẻ h1 sẽ có màu green hay purple?

Câu trả lời là màu purple, các bạn có thể tự mình chứng thực kết quả. Phần giải thích cho bài toán này mình để ở cuối bài viết.

Mình đã không trả lời được câu hỏi này, nhưng thời điểm đó mình cho rằng người phỏng vấn chỉ đang đưa ra câu hỏi mang tính đánh đố thôi, chứ thực tế ai lại viết CSS như vậy. Và sau này mình mới nhận ra, đó không phải là một câu hỏi mang tính đánh đố, mà nó là một phần trong một mảng kiến thức vô cùng quan trọng của CSS, đó là CSS Specificity mà bất kì frontend developer nào cũng cần phải hiểu và nắm vững. Nếu bạn không hiểu hoặc không biết về nó, thì bạn hãy tự vấn mình rằng có phải bạn đang viết CSS theo cảm tính, hoặc theo thói quen hàng ngày hay không.

Ok vậy hãy cùng mình tìm hiểu xem CSS Specificity là gì nhé.

CSS Specificity là gì?

Hãy lấy một ví dụ đơn giản sau để mô tả cho định nghĩa bên dưới:

<div class="parent">
  <span class="child" id="sample">Sample text</span>
</div>
/* thẻ span sẽ có màu gì đây? */
.parent .child {
  color: red;
}

.child {
  color: green;
}

#sample {
  color: blue;
}

Ôi trời, một thẻ span thôi nhưng lại có đến 3 selector cố gắng “tranh nhau” thay đổi màu sắc của nó, giống như một cuộc chiến vậy. Nhưng tin vui là cuộc chiến này sẽ luôn luôn có người chiến thắng, nhờ vào trọng tài là browser. Tuy nhiên browser làm thế nào để xác định người chiến thắng? Câu trả lời là nhờ vào một tập các quy tắc, và browser cứ dựa theo tập quy tắc này để xác định ai là người chiến thắng. CSS Specificity chính là một phần chính yếu trong “tập quy tắc” đấy nhé.

Mình sẽ định nghĩa đơn giản như sau:

Specificity là một trọng số mà browser dựa vào đó để xác định xem một element sẽ có css style là gì. Trọng số chỉ đơn giản như việc 2 > 1 thì 2 chiến thắng, hay 3 > 2 thì 3 chiến thắng, vậy thôi. Một điều cũng quan trọng không kém: Specificity là trọng số của CSS selectors nhé. Nói nôm na hơn, browser sẽ cố gắng xác định xem selector nào là cụ thể nhất (most specific) và style theo selector đó.

“Tập quy tắc” này có phức tạp không? Xác định trọng số Specificity có phức tạp không? Browser dùng tới nó thì chắc hẳn là nó phức tạp lắm? Câu trả lời là nó không hề phức tạp và developer vẫn có thể học thuộc nó một cách dễ dàng. Nói cách khác, 80% các quy tắc là rất đơn giản và dễ hiểu, có thể học thuộc được, còn 20% quy tắc còn lại sẽ khá rối rắm mà ít khi chúng ta sử dụng trong thực tế, nên chúng ta không cần phải nhớ nó, cứ để browser làm việc của nó là được.

Tại sao developer lại nên học thuộc tập quy tắc này (80% các quy tắc thường sử dụng thôi)? Điều này mình không hề chém gió đâu, nếu bạn là một frontend developer chuyên xử lý layout và CSS, thì đây là một kiến thức mà bạn nên nằm lòng, chứ không phải chỉ là để đọc chơi cho biết. Tuy nhiên mình cũng không phải muốn các bạn thuộc nó một cách máy móc, mà nên hiểu nó. Và khi hiểu rồi thì sẽ tự thuộc thôi, hoặc khi quên thì chỉ cần đọc lại tí xíu là nhớ.

Cách xác định trọng số Specificity và cách so sánh

Cách xác định trọng số của CSS selectors chỉ đơn giản là chơi trò chơi đếm số và điền vào 3 ô trống bên dưới thôi.

CSS Specificity là gì vậy?
https://css-tricks.com/specifics-on-css-specificity/

Ở ô đầu tiên (ID), mình sẽ đếm xem selector có bao nhiêu id. Ví dụ #parent { } là 1, #parent #child { } là 2. Đếm xong rồi thì điền vào ô trống thôi.

CSS Specificity là gì vậy?

Ở ô thứ 2, mình sẽ đếm xem có tổng cộng bao nhiêu class (ví dụ .list), psuedo-class (ví dụ :hover) và attribute (ví dụ [type=radio]).

CSS Specificity là gì vậy?

Ở ô thứ 3, mình sẽ đếm xem có tổng cộng bao nhiêu type selector (ví dụ h1), pseudo-element (ví dụ ::before)

CSS Specificity là gì vậy?

Chúng ta cơ bản đã xong bước xác định trọng số rồi, giờ thì so sánh chúng thôi. Cách so sánh cực kì đơn giản, như toán lớp 1 vậy:

  • 1,1,0 lớn hơn 1,0,0 (110 > 100)
  • 0,1,0 lớn hơn 0,0,1 (10 > 1)
  • 1,3,0 lớn hơn 1,0,3 (130 > 103)
  • 0,0,1 bằng với 0,0,1 (1 === 1)

Ồ, nếu bằng nhau thì thế nào? Nếu bằng nhau thì thằng nào được khai báo sau cùng sẽ thắng. Điều này mình sẽ lặp lại ở phần tiếp theo. Giờ thì cùng nhau thực hành đếm trọng số qua các ví dụ sau nhé:

  • #parent: 1,0,0
  • #parent #child: 2,0,0
  • [id="parent"]: 0,1,0
  • li: 0,0,1
  • ul > li: 0,0,2
  • ul ol + li: 0,0,3
  • h1 + *[rel=up]: 0,1,1
  • ul ol li.red: 0,1,3
  • li.red.level: 0,2,1
  • li.name::before: 0,1,2
  • #parent:not(ul): 1,0,1
  • .foo:is(.bar, #bar): 1,1,0

Một số quy tắc khác

Có một số quy tắc khác ít nhiều ảnh hưởng đến trọng số Specificity mà bạn không thể bỏ qua:

  • Universal selector * sẽ được bỏ qua khi xác định trọng số. Ví dụ selector * sẽ có trọng số là 0,0,0. Hay *.foo sẽ có trọng số là 0,1,0. Điều này có nghĩa là *.foo và .foo là hoàn toàn giống nhau.
  • Combinators như +>~|| hay space cũng sẽ được bỏ qua khi xác định trọng số. Ví dụ .parent .child và .parent > .child có cùng trọng số là 0,2,0.
  • :not() không được xem là pseudo-class nên cũng được bỏ qua khi tính trọng số. Tuy nhiên trọng số vẫn sẽ được tính với param truyền vào nó. Ví dụ: div:not(.parent) p sẽ có trọng số là 0,1,2.
  • :is() cũng tương tự với :not(), tuy nhiên vì chúng ta có thể truyền vào một danh sách selector, nên trọng số sẽ được tính với matched selector nào có trọng số cao nhất. Ví dụ: div:is(.parent, #foo) sẽ có trọng số có thể vừa là 0,1,1, vừa có thể là 1,0,1, vừa có thể là 1,1,1, tùy theo việc nó match với bao nhiêu trường hợp. Cũng phức tạp ghê phải không nào.
  • “Inline styles” sẽ luôn luôn có trọng số cao nhất, đánh bật tất cả các đối thủ (ngoại trừ trùm cuối !important). Ví dụ bạn viết:
    <span class="text" style="color: red">text</span>
    

    thì dù bạn cố gắng viết CSS (external CSS) để thay đổi color của nó đều vô ích (tất nhiên như mình đã nói, bạn vẫn có thể nếu dùng đến !important)

    .text {
      color: green; /* không được đâu nhé, nó thua inline style */
    }
    
    .text {
      color: blue !important; /* khi đã dùng tới trùm cuối thì đừng hỏi nữa */
    }
    
  • Trùm cuối của chúng ta !important có thể đánh bại mọi đối thủ, ngay cả inline style vốn đã vô cùng mạnh mẽ. Bạn xem ví dụ ngay phía bên trên là rõ. Tuy nhiên nếu 2 anh trùm cuối cùng đánh nhau thì thế nào? Câu trả lời ở quy tắc ngay bên dưới. Ví dụ:
    .text {
      color: green !important; /* ê blue, đấu với tao không */
    }
    
    .text {
      color: blue !important; /* tao sợ mày à green, chơi luôn */
    }
    
  • Khi 2 hoặc nhiều selector có cùng trọng số, thì selector nào được khai báo cuối cùng sẽ thắng. Trong cuộc đối đầu ở quy tắc bên trên, blue là người chiến thắng. Tất nhiên nếu ta đổi vị trí 2 selector này cho nhau, thì green lại là người chiến thắng. Đây là một lỗi thường thấy khi chúng ta không am hiểu về Specificity (thường là các bạn junior), vô tình thay đổi vị trí hoặc chỉnh sửa CSS vô tội vạ làm thay đổi trọng số, dẫn đến lỗi style không mong muốn.

Độ gần/xa (proximity) có ảnh hưởng không?

Thật sự mình không biết nên dịch từ “proximity” thế nào cho đúng, nhưng ý nghĩa của nó có hiểu qua ví dụ ở đầu bài viết.

<html>
  <head>
    <style>
      body h1 { color: green; }
      html h1 { color: purple; }
    </style>
  </head>

  <body>
    <h1>text</h1>
  </body>
</html>

“Proximity” ám chỉ việc thẻ h1 gần với body hơn là html, vậy liệu selector body h1 có trọng số lớn hơn html h1 không? Câu trả lời là KHÔNG.

Trong trường hợp này, vì cả 2 đều có cùng trọng số là 0,0,2, chúng ta sẽ sử dụng quy tắc “thằng nào được khai báo cuối cùng sẽ thắng”. Vậy kết quả sẽ là html h1 chiến thắng, màu của thẻ h1 sẽ là purple.

Lưu ý & suy ngẫm

  1. Một selector với trọng số lớn liệu có tốt không? Ví dụ:
    /* Trọng số là 2,3,4 */
    #main article.sports table#stats tr:nth-child(even) td:last-child {
      ...
    }
        

    Với trọng số là 2,3,4, bạn sẽ rất khó để override nó, và sẽ làm cho code của bạn rối rắm và khó để maintain hay extend.

  2. Bất kì khi nào bạn rơi vào tình huống không hiểu vì sao element của mình lại có style không như mong muốn, thì Specificity sẽ giúp bạn. Tuy nhiên thay vì ngồi đếm trọng số bằng tay, giờ đây với công cụ devtools mạnh mẽ của các browser thì việc xác định lỗi style là vô cùng đơn giản. Tuy nhiên các công cụ này cũng xây dựng trên nguyên lý CSS Specificity mà thôi chứ không có gì khác biệt đâu.
  3. Specificity chỉ có ý nghĩa nếu một element có nhiều selector cùng trỏ (target) đến nó. Nói nôm na là nếu cuộc chiến mà chỉ có 1 người tham gia thì hiển nhiên người đó thắng rồi.
  4. Trong CSS có việc kế thừa style từ các element cha. Tuy nhiên việc kế thừa này sẽ luôn xếp sau những selector trỏ (target) đích danh đến element nhé. Bạn để ý khi sử dụng devtools là thấy thôi.
  5. Việc có nên sử dụng inline styles không vẫn là một vấn đề gây tranh cãi. Một số linter sẽ warning nếu bạn viết inline styles, nhưng bạn vẫn có thể tắt warning đó đi nếu muốn. Một trong những lý do là vì trọng số của nó quá cao sẽ dễ gây ra các lỗi không mong muốn, hoặc sẽ rất khó để override và buộc phải dùng đến !important. Một lý do khác nữa là với nhiều “chuyên gia” thì CSS nên đặt trong các file .css để dễ quản lý, chứ nếu nằm trong style (html) thì rối loạn lên hết?
  6. Mặc dù trùm cuối !important vô cùng mạnh mẽ, việc dùng đến !important không phải là một giải pháp tốt và cần hạn chế sử dụng, giống như inline styles mà mình vừa đề cập đến. Trước khi buộc phải dùng đến !important, bạn hãy suy xét cẩn thận xem chúng ta có thể sử dụng CSS Specificity để đạt được mục đích hay không.

BEM & ITCSS

Ở đây mình không phải muốn giải thích hay giới thiệu chi tiết về 2 “phương pháp” này, mà chỉ muốn chỉ ra một vài điểm liên quan với Specificity thôi. Ngoài BEM và ITCSS ra còn có nhiều phương pháp khác nữa, nhưng cơ bản đều xây dựng trên Specificity cả.

BEM: mình mặc định bạn đã biết đến BEM, thì một vài tôn chỉ của nó có thể kể đến như:

  • Tránh sử dụng id (#foo): lý do thì như mình đã chia sẻ, id có trọng số lớn và khá khó để override, nên việc cố gắng override nó sẽ dễ đẩy CSS của bạn đến một tương lai không mấy sáng sủa.
  • Tránh nested selector, cố gắng làm phẳng selector: cũng cùng lý do, nested selector cũng làm tăng trọng số của selector. Ví dụ BEM sẽ khuyến khích:
    /* BEM thích điều này, trọng số chỉ là 0,1,0
    nhưng vẫn rất specific và khó bị conflict */
    .block {}
    .block__elem1 {}
    .block__elem2 {}
    .block__elem3 {}
    
    /* Trọng số sẽ là 0,2,0, cũng không quá tệ, nhưng BEM không khuyến khích,
    và nó cũng rất dễ bị conflict. */
    .block {}
    .block .elem1 {}
    .block .elem2 {}
    .block .elem3 {}
        

ITCSS: cũng là một phương pháp ứng dụng triệt để các quy tắc của CSS Specificity, giúp CSS của bạn có thể dễ dàng scale, extend và maintain (SEM). ITCSS có rất nhiều thứ để nói nhưng nằm ngoài phạm vi bài viết nên mình xin dừng ở đây, nếu các bạn quan tâm thì để lại comment để mình làm một bài viết riêng về nó nhé.

CSS Specificity calculator

Chỉ cần search google là bạn sẽ thấy một vài tool sẽ giúp bạn xác định trọng số của selector:

https://polypane.app/css-specificity-calculator/
https://www.codecaptain.io/tools/css-specificity-calculator
https://isellsoap.github.io/specificity-visualizer/

Tuy nhiên các bạn cũng không nên hoàn toàn tin tưởng vì các tool này chỉ đếm trọng số trong những trường hợp đơn giản, còn những trường hợp phức tạp hơn thì vẫn có thể sai nhé.

Mình chốt lại bài viết bằng một tấm hình vui nhưng khá nổi tiếng nhé.

CSS Specificity là gì vậy?
https://specifishity.com/

Lời kết

CSS cơ bản thật ra cũng không nhiều, bạn chỉ cần biết vừa đủ là có thể tung hoành giang hồ được rồi. Vì nó không nhiều và cũng không khó, nên các bạn hãy dành thời gian học và nắm vững nó nhé. Trước giờ mình đi phỏng vấn với vị trí frontend, mình thấy khá hiếm công ty nào phỏng vấn về CSS, có lẽ họ mặc nhiên rằng frontend developer thì phải biết CSS, hoặc bản thân họ không thích CSS nên không muốn đặt câu hỏi. Nhưng nếu vô tình được hỏi, thì hãy “chém tơi bời” interviewer nhé 😀

Như mọi lần, nếu các bạn thấy bài viết có gì thiếu sót hay sai chỗ nào thì vui lòng để lại comment cho mình biết để sửa đổi. Nếu các bạn thấy bài viết hay và hữu ích thì upvote hoặc comment để mình có động lực viết tiếp các bài tiếp theo nhé.

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

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

Xem thêm các tuyển dụng CSS hấp dẫn tại TopDev

Viết một chatbot đơn giản với Python3

Viết một chatbot đơn giản với Python3

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

Chatbot là gì?

Trước khi thò tay vào hì hục code, ta cần hiểu chatbot là gì đã?

Chatbot là một chương trình thực hiện cuộc hội thoại qua phương pháp gửi nhận văn bản hoặc các object như hình ảnh, file, … Chú ý Chatbot không nhất thiết là phải thông minh, là phải dùng trí tuệ nhân tạo, etc …

Có bao giờ sắp đến giao thừa hay một dịp mà bạn muốn nhắn tin cho nhiều người vào 12h đêm mà bạn không thể dậy được, hoặc bạn quá lười để làm một việc lặp đi lặp lại? Câu trả lời là viết một chatbot và hẹn giờ cho nó.

  Trải nghiệm lần đầu viết thư viện Python từ ngôn ngữ biên dịch

Viết chatbot

Trong bài viết này mình sử dụng 2 thư viện có sẵn trên mạng là fbchatschedule do đó bạn cần tạo virtualenv trước tiên, sau đó dùng pip để cài 2 lib trên rồi tạo một file code python tùy ý, ở đây mình dùng chatbot.py.

Đầu tiên, import những lib mình cần

import logging
import os
import time
from threading import Thread
from fbchat import Client
from fbchat.models import Message, ThreadType
import schedule

Sau đó tạo một class Bot kế thừa Client:

class Bot(Client):

Tạo 1 function trong class Bot để thực hiện gửi tin nhắn, dưới đây là code của mình:

class Bot(Client):
    def do_something(self):
        #Đổi tên function cho phù hợp
        logging.basicConfig(level=logging.INFO)
        lst_id = [...] # List chứa fb id của những người bạn muốn gửi
        for user_id in lst_id:
            self.send(Message(text="Chúc mừng năm mới"),
                      thread_id=user_id, thread_type=ThreadType.USER)
            self.sendLocalImage('/home/dosontung007/Pictures/wallpaper.png', message=Message(text='Chúc mừng năm mới'),
                                thread_id=user_id, thread_type=ThreadType.USER)
            logging.info('Sent success to %s' % str(user_id))

Và để nhận được tin nhắn từ những người gửi cho mình cho mình , ta viết function onMessage trong class Bot và xử lí các tin nhắn đó:

def onMessage(self, message_object, author_id, thread_id, thread_type, **kwargs):
    lst_msg = list('Chúc mừng năm mới')
    if author_id != self.uid and message_object.text in lst_msg:
        self.send(Message(text='Năm mới chúc .....'),
                  thread_id=author_id,
                  thread_type=thread_type)

Tham khảo thêm tại https://fbchat.readthedocs.io/en/master/

  Tại sao phải chọn giữa R hay Python trong khi bạn có thể chọn cả 2?

Job thực hiện việc gửi tin nhắn trong này đó là:

Bot(os.environ['USERNAME_'], os.environ['PASSWORD']).do_something()

Class Bot kế thừa Client, khi tạo một Bot object, ta cần truyền 2 tham số là username và password của Facebook của bạn. Do đó bạn cần set value cho 2 var USERNAME_ và PASSWORD bằng câu lệnh export var=value trong bash trước khi chạy chương trình (vì ta không muốn ghi trực tiếp password vào file code – lộ mật khẩu nếu up lên GitHub). Lưu ý USERNAME_ chứ không phải USERNAME.

Bây giờ còn một công việc duy nhất là hẹn giờ cho job làm việc thôi!

def job():
    Bot(os.environ['USERNAME_'], os.environ['PASSWORD']).do_something()


def send_msg():
    schedule.every().day.at('00:00').do(job_that_executes_once))

    while True:
        schedule.run_pending()
        time.sleep(1)

Thay đổi 00:00 bằng thời gian mà bạn muốn hẹn giờ.

Để nhận được message, ta sử dụng function listen từ Client , về cơ bản listen khi chạy sẽ truyền các arguments vào onMessage mỗi lần Facebook bạn có event mới (VD: có người nhắn cho bạn, bạn nhắn cho người khác hoặc tin nhắn trong nhóm, …):

def reply_msg():
    Bot(os.environ['USERNAME_'], os.environ['PASSWORD']).listen()

Ở function main, mình sử dụng lib threading để chạy song song 2 job là reply_msg và send_msg :

def main():
    Thread(target=send_msg).start()
    Thread(target=reply_msg).start()

Cuối cùng cũng xong .Sau tất cả, đây là một con chatbot hoàn chỉnh :

import logging
import os
import time
from threading import Thread

from fbchat import Client
from fbchat.models import Message, ThreadType
import schedule


class Bot(Client):
    def onMessage(self, message_object, author_id, thread_id, thread_type, **kwargs):
        lst_msg = list('Chúc mừng năm mới')
        if author_id != self.uid and message_object.text in lst_msg:
            self.send(Message(text='Năm mới chúc .....'),
                      thread_id=author_id,
                      thread_type=ThreadType.USER)


    def do_something(self):
        logging.basicConfig(level=logging.INFO)
        user_ids = ['100012610305665']
        for user_id in user_ids:
            self.send(Message(text="Chúc mừng năm mới"),
                      thread_id=user_id, thread_type=ThreadType.USER)
            self.sendLocalImage('/home/dosontung007/Pictures/wallpaper.png', message=Message(text='Chúc mừng năm mới'),
                                thread_id=user_id, thread_type=ThreadType.USER)
            logging.info('Sent success to %s' % "100012610305665")


def job_that_executes_once():
    Bot(os.environ['USERNAME_'], os.environ['PASSWORD']).something()
    return schedule.CancelJob


def reply_msg():
    Bot(os.environ['USERNAME_'], os.environ['PASSWORD']).listen()


def send_msg():
    schedule.every().day.at('00:00').do(job_that_executes_once))
    while True:
        schedule.run_pending()
        time.sleep(1)


def main():
    thread1 = Thread(target=send_msg)
    thread2 = Thread(target=reply_msg)

    thread1.start()
    thread2.start()

    thread1.join()
    thread2.join()


if __name__ == '__main__':
    main()

Bây giờ export username, password rồi chạy thôi. Và đây là thành quả:

Viết một chatbot đơn giản với Python3

Nếu bạn muốn chạy luôn mà không cần hẹn giờ thì chỉ cần xoá function job_that_executes_once và thay function send_msg bằng:

def send_msg():
    Bot(os.environ['USERNAME_'],os.environ['PASSWORD']).do_something()

HẾT.

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

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

Xem thêm tuyển dụng python nhiều vị trí hấp dẫn tại TopDev

Top 5 API thú vị dành cho các New Developers

Top 5 API cho các New Developers

Bài gốc được viết bởi tác giả Elle Townsend

Khi đang cố gắng để cải thiện kỹ năng Front-end và JavaScript của mình, tôi đã nảy ra ý tưởng học thêm về các API. Dưới đây tôi sẽ chia sẻ với mọi người một số API thú vị mà tôi hay sử dụng.

API là gì?

API – Application Programming Interface là phương thức trung gian kết nối các ứng dụng và thư viện khác nhau. Nó cung cấp khả năng truy xuất đến một tập hợp các hàm hay dùng, từ đó có thể trao đổi dữ liệu giữa các ứng dụng. Bên cạnh đó, các phương thức này sử dụng mã nguồn mở, dùng được với mọi client hỗ trợ XML, JSON và được đánh giá là một trong những kiểu kiến trúc hỗ trợ tốt nhất với các thiết bị có lượng băng thông bị giới hạn như smartphone, tablet…

Xem thêm Top 20 API trong AI và Machine Learning bạn nên biết

topdev

Một số API được sử dụng nhiều:

1. REST Countries

REST Countries là nguồn tài nguyên hữu ích để tạo các dự án mới. Nó lưu trữ tài liệu của nhiều lĩnh vực khác nhau từ đơn vị tiền tệ, thủ đô quốc gia đến các ngôn ngữ trên khắp thế giới. Cá nhân tôi từng tạo API calls trong Vue.js với Axios.

2. The PokéAPI

Tôi rất thích nền tảng này, The PokéAPI cũng là phương thức đầu tiên tôi sử dụng và đã thực hiện một số dự án bằng API này. PokéAPI chứa nguồn dữ liệu lớn đặc biệt phù hợp với những người mới bắt đầu, không giới hạn về tỉ lệ và có mọi thứ bạn cần để tạo một PokéDex của riêng mình.

  20 trường hợp sử dụng lệnh Docker cho developer
  Software Developer và 5 bài học kinh nghiệm quan trọng

3. Translation APIs

Có rất nhiều API để dịch văn bản sang các ngôn ngữ khác nhau bao gồm cả Yandex Translator và Google translate. Đặc biệt, với những nhân vật trong các tác phẩm kinh điển như Elvish – Chúa tể của những chiếc nhẫn, Yoda – Chiến tranh giữa các vì sao hay Groot – Vệ binh dải ngân hà họ đều không nói ngôn ngữ của loài người, các translation APIs còn cho phép chúng ta dịch được cả tiếng của họ trong phim nữa.

4. Affirmations API

Affirmations API được Tilde Ann Thurium tạo trên Github cho phép bạn truy cập thư viện những affirmation dễ nhìn nhất. Truy cập https://www.affirmations.dev/ và bạn sẽ được recommend những ý tưởng affirmation sáng tạo nhất và áp dụng cho dự án của mình.

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

5. Spotify

Nếu vẫn không có API nào thật sự thu hút bạn thì hãy thử cân nhắc đến khía cạnh âm nhạc xem. Spotify có một nền tảng với các nguồn dữ liệu mở về thông tin ca sĩ, nhạc sĩ, bài hát, album, tạo và hiển thị danh sách phát và kể cả tạo một giao diện Spotify cho riêng cá nhân bạn luôn.

Kết luận

Hy vọng rằng một số API trên đây sẽ có thể cho bạn thêm thông tin cần thiết và hữu ích với các dự án tiếp theo của bạn.

Bài viết gốc được đăng tải tại medium.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

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