Home Blog Page 169

9 câu hỏi lắt léo về Promise

câu hỏi lắt léo về Promise

1.

var p = new Promise((resolve, reject) => {
  reject(Error('The Fails!'))
})
p.catch(error => console.log(error.message))
p.catch(error => console.log(error.message))

Kết quả output

  1. Kết quả lỗi log ra 1 lần
  2. Kết quả lỗi log ra 2 lần
  3. UnhandledPromiseRejectionWarning

.catch sẽ làm việc giống như .addEventListener(event, callback) hay Event Emitter .on(event, callback). Có thể add thêm bao nhiêu tùy thích, nó số chạy tất cả các callback đã đăng ký

2var p = new Promise((resolve, reject) => {
  return Promise.reject(Error('The Fails!'))
})
p.catch(error => console.log(error.message))
p.catch(error => console.log(error.message))
  1. Kết quả lỗi log ra 1 lần
  2. Kết quả lỗi log ra 2 lần
  3. UnhandledPromiseRejectionWarning

Khi khởi tạo một Promise, chúng ta phải gọi một trong hai callback resolve() hoặc reject(). Nó ko return giá trị. Không thể dùng Promise.reject() như ở trên. Đáp án: UnhandledPromiseRejectionWarning

3

var p = new Promise((resolve, reject) => {
    reject(Error('The Fails!'))
  })
  .catch(error => console.log(error))
  .then(error => console.log(error))

 

Kết quả

  1. In ra lỗi và undefined
  2. in ra lỗi 2 lần
  3. UnhandledPromiseRejectionWarning
  4. undefined

annotated-code/question-3.png

Gợi ý thứ nhất console.log() luôn trả về undefined. Thứ 2, khi đặt .catch trước .then như thế, nó sẽ không nhận được giá trị từ hàm trước đó, mọi thứ đã dừng lại ở catch. Đáp án In ra lỗi và undefined

4

var p = new Promise((resolve, reject) => {
    reject(Error('The Fails!'))
  })
  .catch(error => console.log(error.message))
  .catch(error => console.log(error.message))

 

  1. In ra lỗi một lần
  2. In ra lỗi 2 lần
  3. UnhandledPromiseRejectionWarning

Giải thích như trên, câu catch thứ 2 không được gọi đến, điều đặc biệt là bạn có thể đặt .then ở phía sau catch nhưng không thể đặt catch sau catch. Đáp án: In ra lỗi 1 lần

5

new Promise((resolve, reject) => {
    resolve('Success!')
  })
  .then(() => {
    throw Error('Oh noes!')
  })
  .catch(error => {
    return "actually, that worked"
  })
  .catch(error => console.log(error.message))

 

  1. In lỗi 1 lần
  2. In lỗi 2 lần
  3. UnhandledPromiseRejectionWarning
  4. Ko in gì cả

catch có thể được sử dụng để bỏ qua hoặc ghi đè lên giá trị lỗi bằng cách cho return một giá trị. Trò này chỉ làm được khi trước đó then có trả về giá trị. Đáp án: không in gì cả

6

Promise.resolve('Success!')
  .then(data => {
    return data.toUpperCase()
  })
  .then(data => {
    console.log(data)
  })

 

  1. In ra “Success!” và “SUCCESS!”
  2. In ra “Success!”
  3. In ra “SUCCESS!”
  4. Không in ra gì cả

.then sẽ truyền dữ liệu theo thứ tự đã viết, khi return giá trị, hàm then tiếp thiệu sẽ nhận giá trị return này. Đáp án: In ra “SUCCESS!”

7

Promise.resolve('Success!')
  .then(data => {
    return data.toUpperCase()
  })
  .then(data => {
    console.log(data)
    return data
  })
  .then(console.log)

 

  1. In ra “SUCCESS!”
  2. In ra “Success!”
  3. In ra “SUCCESS!” và “SUCCESS!”
  4. Không in ra gì cả

Giải thích tương tự như trên. Đáp án: In ra “SUCCESS!” và “SUCCESS!”

8

Promise.resolve('Success!')
  .then(data => {
    data.toUpperCase()
  })
  .then(data => {
    console.log(data)
  })

 

  1. In ra “SUCCESS!”
  2. In ra “Success!”
  3. In ra “SUCCESS!” và “SUCCESS!”
  4. In ra “undefined”

Nếu muốn truyền giá trị xuống .then bên dưới, trước đó phải return. Đáp án: In ra “undefined”

9

Promise.resolve('Success!')
  .then(() => {
    throw Error('Oh noes!')
  })
  .catch(error => {
    return 'actually, that worked'
  })
  .then(data => {
    throw Error('The fails!')
  })
  .catch(error => console.log(error.message))

 

  1. In ra “Oh noes!” và “The fails!”
  2. In ra “Oh noes!”
  3. In ra “The fails!”
  4. In ra “actually, that worked”
  5. Không in ra gì cả

Tổng hợp những kiến thức ở trên, hy vọng bạn trả lời đúng câu này. Ở then đầu tiên, chúng ta throw một error, catch tiếp theo chúng ta return coi như bỏ qua error này, then thứ 2, nhận data nhưng chúng ta ko làm gì với nó cả, mà throw một error khác, catch cuối cùng sẽ là giá trị error vừa throw ở trên. Đáp án: In ra “The fails!”.

TopDev via Vuilaptrinh

Xem thêm các vị trí tuyển dev lương cao tại đây

Bảo mật web – Một số kiểu tấn công

Tổng quát các vấn đề bạn cần quan tâm để bảo mật ứng dụng web

Cách quản lý Session hiện tại

HTTP = stateless

  • Tất cả request từ cùng 1 client không liên quan gì với nhau
  • Server không có cách nào để lưu tạm giá trị state HTTP hỗ trợ gửi đi dữ liệu authentication
  • Thông qua Header.Authorization
  • Gửi thông tin kèm theo tất cả request
  • Server không can thiệp gì trên từng session

Session quản lý bởi server

Server toàn quyền kiểm soát session, kiểm tra tình trạng active, expire, invalid date, xóa session

Đại diện cho cách này là dùng Cookie

  • Dữ liệu được truyền qua lại giữa server và client
  • Hầu hết các trình duyệt đều hỗ trợ, khó, nếu sử dụng bên ngoài trình duyệt (ứng dụng điện thoại chẳng hạn)
  • Bị tấn công CSRF

Theo mặc định các request sẽ không nên gửi kèm thông tin xác thực tài khoản (ví dụ cookie), nếu cần gửi thêm thông tin này bằng thiết đặt withCredentials thủ công, phía server đồng thời cũng gửi lại trong response header giá trị Access-Control-Allow-Credentials: true

Session quản lý ở client

Đưa toàn bộ thông tin session xuống phía client Server không kiểm soát session nào đang active Dữ liệu session được gửi đi trên mỗi request

Đại diện cho kiểu này là dùng Token (JWT đang là phổ biến nhất)

  • Dữ liệu session được lưu xuống token, server gửi token này qua HTTP header hoặc body của response
  • Ứng dụng tự quản lý chuyện gửi server token này
  • Trên mỗi request gửi đi nó không tự chèn token vào, do đó nó không thể tấn công bằng CSRF
  • Mồi ngon của tấn công XSS

Một số kiểu tấn công

CSRF (Cross-Site Request Forgery)

Kiểu tấn công rất phổ biến, nếu thông tin session được gửi qua Cookie. Đại khái là nếu bạn đăng nhập vào facebook.com, sau đó truy cập vào trang web nào đó bị hack rồi, trang bị hack này sẽ gửi một trang có nội dung html bên trong đó nó dùng một thẻ nào đó (như <img /><iframe/><link/><bgsound/><background />) để gửi một request thay đổi email lên trang facebook.com

<iframe height="0" width="0" src="facebook.com/api/1/destroy">
<link ref="stylesheet" href="facebook.com/api/1/destroy" type="text/css"/>
<bgsound src="facebook.com/api/1/destroy"/>
<background src="facebook.com/api/1/destroy"/>
<img height="0" width="0" src="facebook.com/api/1/destroy"/>

 

CSRF (Cross-Site Request Forgery)

Cách ngăn chặn #1: Sử dụng HTML token

Dấu token bên trong HTML, ví dụ như nhét nó trong form, server khi nhận được sẽ kiểm tra lại để chắc chắn là token này hợp lệ

<form action="submit.php">
  <input type='hidden' name='CSRFToken' value='OWY4NmQwODE4ODRjN2Q2NTlhMmZlYWEwYzU1YWQwMTVhM2JmNGYxYjJiMGI4MjJjZDE1ZDZMGYwMGEwOA==' />
</form>

 

Tuy nhiên cách này sẽ không thích hợp với SPA, vì yêu cầu phía server phải quản lý session của từng user đang login

Cách ngăn chặn #2: Origin Header

Với những request như POST/PUT/DELETE, tự động thêm Origin Header để xác thực yêu cầu

Cách ngăn chặn #2: Origin Header

Cách ngăn chặn #2: Origin Header

Cách ngăn chặn #3: dùng transparent token

So sánh giá trị cookie với giá trị header

User gửi đi một request, nó nhận được 1 Session Cookie và 1 CSRF Token Cookie.

Set-Cookie: session=...
Set-Cookie: CSRF-Token=123

 

Khi ứng dụng gửi đi một request, javascript sẽ copy cookie và đưa vào header X-CSRF-Token chỉ javascript trên trang hiện tại mới truy xuất được thông tin này

Cookie: session=...
Cookie: CSRF-Token=123
X-CSRF-Token: 123

 

Server đơn giản là kiểm tra 2 giá trị Cookie: CSRF-Token và X-CSRF-Token có khớp không

Cross-Site Scripting (XSS)

Hacker sẽ tìm cách để chạy javascript trên trang trình duyệt của user, khi user truy cập vào một trang đã bị hack. Hacker sẽ dùng những cách sau

Store XSS – lưu đoạn script đó lên trên server

Cross-Site Scripting (XSS)

Reflect XSS

Reflect XSS

DOM-Based XSS

Reflect XSS

Cách phổ biến để phòng chống

  • Filter hết mấy đoạn html nguy hiểm (như < >, ” “, &) trước khi lưu
  • Dùng thư viện để escape context-sensitive trước khi output

Công cụ kiểm tra

Một số trang online để check

https://securityheaders.com/

https://sitecheck.sucuri.net/

https://www.ssllabs.com/ssltest/

https://quttera.com/

https://detectify.com/

https://app.webinspector.com/

https://app.upguard.com/webscan

Getting Single Page Application Security Right by Philippe De Ryck

TopDev via Vuilaptrinh

5 biểu hiện của nhân viên cần cân nhắc sa thải

05-bieu-hien-cua-nhan-vien-ma-nguoi-tuyen-dung-phai-can-nhac-sa-thai

Có nhiều lý do để người quản lý buộc thôi việc nhân viên mình. Đó có thể dựa trên những đánh giá từ kết quả công việc, sự phù hợp – tính ổn định về lâu dài, phẩm chất nhân viên,… hay bất cứ một lý do nào đó.

Thực tế đã cho thấy, chuyện chấm dứt hợp đồng làm việc với nhân viên mình chưa bao giờ là một quyết định dễ dàng với các nhà quản lý. Tuy nhiên, với một nhân viên có những biểu hiện sau, việc sa thải là điều hiển nhiên phải thực hiện.

  Bí mật giúp tạo động lực và tăng năng suất cho nhân viên!
  Công nghệ gắn kết nhân viên - vũ khí mới của HR trong thời đại mới

1. Thường xuyên phàn nàn hay đòi hỏi

Những nhân viên tệ trong quá trình làm việc sẽ có xu hướng phàn nàn, than vãn về nhiều việc diễn ra xung quanh. Có thể là đồng nghiệp, môi trường làm việc, khối lượng công việc đảm nhận và trong mắt họ, không có gì là hoàn hảo. Và nếu để kéo dài, họ có thể là những tạo ra những ảnh hưởng tiêu cực đến với sự phát triển của tổ chức/doanh nghiệp.

5 biểu hiện của nhân viên cần cân nhắc sa thải

Cụ thể họ có những biểu hiện hành vi như sau:

1. Thường xuyên tìm kiếm nhiều điều để khiếu nại, phàn nàn về những sai lầm của đồng nghiệp. 

2. “Tạo sóng” bằng cách lan truyền những tin đồn tạo ra sự thị phi

3. Nói xấu sau lưng đồng nghiệp.

Không những thế, những nhân viên này đôi khi còn đòi hỏi quá nhiều điều về các nhu cầu khác nhau. Có thể họ sẽ đòi hỏi về mức lương trong khi bản thân mình không tự đánh giá được khả năng của mình hoặc đòi hỏi những nhu cầu mà họ xem là cấp thiết như: các thiết bị hỗ trợ, chính sách phúc lợi xã hội,..

2. Thiếu tinh thần trách nhiệm

Không một công ty nào mong muốn nhân viên của mình thiếu trách nhiệm với công việc cả. Và để tránh làm ảnh hưởng đến tinh thần làm việc của mọi người và ảnh hưởng lớn đến chiến lược xây dựng và sự phát triển chung của công ty thì những đối tượng nhân viên có các biểu hiện sau đây cần được xem xét “thanh lọc” sớm: 

  • Hay đổ lỗi cho hoàn cảnh khi chưa hoàn thành tốt nhiệm vụ được giao, đỗ lỗi cho người khác
  • Thực hiện và giải quyết công việc hời hợt, không tập trung
  • Luôn viện cớ bào chữa cho những hạn chế, sai phạm do bản thân gây ra 
  • Không hề có sự biểu hiện nào của sự cố gắng
  • Chiếm dụng quỹ thời gian để làm việc riêng

3. Thiếu tập trung và thái độ

Ngoài năng lực chuyên môn, thái độ sống tích cực thì nhiệt huyết và sự đam mê trong công việc rất quan trọng. 

5 biểu hiện của nhân viên cần cân nhắc sa thải

Cụ thể khi một dự án mới được triển khai, họ thường tỏ ra không mấy hứng thậm chí uể oải khi tiếp nhận thông tin. Ngược lại, họ lại tỏ thái độ thiếu hợp tác và họ thuộc kiểu người dễ nản chí khi gặp một chút khó khăn. Chính vì vậy mà nếu tiếp diễn lâu dài họ sẽ truyền đi năng lượng xấu cho các nhân viên khác và ảnh hưởng xấu đến bầu không khí làm việc chung của mọi người.

Sự thiếu nhiệt huyết đôi khi còn được thể hiện thông qua sự lười biếng hoặc thậm chí nhân viên đó nghỉ việc quá nhiều. Một nhân viên tự ý nghỉ việc không lý do chính đáng, thiếu nhiệt huyết trong công việc thì khó có thể hoàn thành tốt nhiệm vụ được giao.

4. Không có tinh thần làm việc nhóm

Việc tập trung vào công việc của mình là tốt, đó cho thấy bạn thật sự có trách nhiệm với phần việc của mình đồng thời cũng là một cách hiệu quả để rèn luyện khả năng tư duy độc lập. Tuy vậy, để phát triển sự nghiệp lâu dài, bạn không phải làm việc độc lập một mình mà cần sự hợp tác nhóm, nên việc giúp đỡ, trao đổi với ai đó là điều cần thiết.

Đặc biệt hơn không riêng gì giới nhân sự, nếu muốn phát triển và thăng tiến trong sự nghiệp thì việc nhân viên phải cọ xát và trải nghiệm nhiều vai trò, vị trí để nắm bắt tốt suy nghĩ, mong muốn của họ là điều thật sự cần thiết. Và làm việc nhóm chính là cơ hội để nhân viên thử sức học hỏi những điều này.

Nếu cứ chỉ chăm chăm làm việc của mình mà không quan tâm đến thành quả chung mang tính đồng đội, không hiểu giá trị của sự cộng tác thì bạn sẽ mãi chậm chân tại chỗ, mãi vẫn là một ngôi sao không bao giờ sáng.

5. Thiếu sự chủ động và sự sáng tạo

Môi trường làm việc năng động và không ngừng cập nhật những xu hướng mới. Vì thế, việc nhân viên cần phải chủ động và rèn luyện tính sáng tạo trong công việc là một điều cần thiết.

Sự chủ động có thể hiểu là sự linh hoạt trong suy nghĩ dẫn đến biểu hiện cụ thể qua hành động. Ví dụ như bạn bày tỏ những quan điểm, sáng kiến mới về vấn đề, mạnh dạn đóng góp những ý kiến, đánh giá, đề xuất của cá nhân trong các cuộc họp của tổ chức,…. Ngoài ra, việc tự trau dồi thêm  kiến thức bổ trợ từ các khóa học chuyên sâu cũng là cách để phát triển năng lực của mình. Tương tự, để có thể tiếp tục theo đuổi công việc, bạn cần có sự sáng tạo để có những lối tư duy mới, tránh những đường hướng cũ. Cá nhân mọi tổ chức doanh nghiệp đều mong muốn nhân viên của họ có tính chủ động và sáng tạo trong công việc.

Đôi khi bạn có thể chưa sáng tạo nhưng sự chủ động có thể thay thế và ngược lại đồng thời, bạn phải có sự thích ứng tốt với công việc, luôn tìm tòi, học hỏi và tự phát triển bản thân theo lộ trình riêng. Hãy thể hiện cho người quản lý thấy sự nỗ lực của bạn như thế nào, sự thay đổi tích cực của bạn ra sao thông qua các thành quả thay vì chỉ mãi thụ động và chậm chân tại chỗ.

Có rất nhiều biểu hiện cho thấy đó là một nhân viên không phù hợp. Tuy nhiên, các nhà quản lý cần sáng suốt trong việc đưa ra những chiến lược để giải quyết kịp thời trước những thái độ của nhân viên. Một chiến lược hợp lý và thể hiện được ủy quyền của nhà quản lý sẽ là bài học sâu sắc cho mỗi cá nhân nhân viên nhìn nhận lại sự thiếu sót của mình, giúp họ hoàn thiện hơn trên hành trình nghề nghiệp. 

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

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

13 web hosting miễn phí dành cho lập trình viên

13 web hosting miễn phí dành cho lập trình viên

Mong muốn của dev mọi nhà đôi khi đơn giản chỉ là một trang hosting đủ tính năng, quan trọng là miễn phí để test thôi. Sao không bỏ túi ngay top 13 hosting web, có đủ các chức năng và còn không tốn đồng nào trong list dưới đây? Lưu về ngay để lúc nào cần chỉ cần mở lên dùng thôi nhé.

Infinity Free

13 web hosting miễn phí dành cho lập trình viên

Có nhiều lý do khiến Infinity Free đứng đầu bảng Free Web Hosting như là băng thông không giới hạn, tốc độ tải cực nhanh bao gồm lượng uptime của hosting này đạt đến 99%. Ngoài ra yếu tố quan trọng nhất là Disk Space không giới hạn và không hề có ads. Những ứng dụng phổ biến của Infinity Free bao gồm WordPress, Joomla, Drupal, MyBB, PrestaShop, PhpBB. Bạn còn có thể host 10 tài khoản email miễn phí và 400 cơ sở dữ liệu MySQL với không gian không giới hạn.

FREEHOSTIA

Tương tự với Infinity Free nhưng Freehost có những giới hạn và đặc tính riêng. Freehostia cho phép web hosting cloud miễn phí. Người dùng có thể host 5 domains mỗi tài khoản với 250MB mỗi Disk Space (dung lượng lưu trữ) và 6GB băng thông hàng tháng.

000webhost

13 web hosting miễn phí dành cho lập trình viên

000webhost là trang web hosting miễn phí với Cpanel, hoàn toàn free với PHP, MySQL, cPanel và không có ad. Ngoài ra 000webhost đảm bảo lượng Uptime 99.9%, 1Gb Disk Space và 10Gb băng thông.

BYET

Byet cho phép dịch vụ hosting web miễn phí không ads bao gồm PHP, MySQL, FTP, Vistapanel. Bạn có thể tham khảm domain “yoursite.byethost.com” và 7 lựa chọn khác trang này đưa ra. Mục tiêu hàng đầu của BYET là dẫn đầu các trang server về Uptime, họ cho phép PHP 5.4 đến 7.0. Free FTP, MySQL. Ngoài ra người dùng có thể xây dựng tính năng build SEO để cải thiện điểm tối ưu hóa công cụ tìm kiếm (SEO).

Googiehost

13 web hosting miễn phí dành cho lập trình viên

Cũng như Byet, Googiehost cho phép host web free với Cpanel, nhiều tính năng với những công nghệ mới nhất. Googiehost cung cấp storage lên đến 1000 MB SSD với băng thông không giới hạn bao gồm Uplink 100MBPS. Họ cung cấp những tài khoản email doanh nghiệp miễn phí không giới hạn, người dùng có thể tạo Subdomain thoải mái.

Freehosting.io

13 web hosting miễn phí dành cho lập trình viên

Freehosting.io cung cấp dịch vụ shared hosting hoàn toàn free cùng những tính năng bảo mật tốt nhất và dịch vụ hỗ trợ 24/7, với hơn 50+ địa điểm server trên toàn thế giới. Hiện nay đang có khoảng hơn 70 nghìn website đang chạy trên nền tảng Freehosting.io mà không có Downtime.

Với lượng Disk Space và băng thông vô hạn, người dùng có thể sử dụng bao nhiêu tùy thích, ngoài ra họ còn có thêm tính năng Drag and Drop (kéo thả) đi kèm với rất nhiều template. Với 3 bước sau bạn có thể dựng một trang web miễn phí:

  • Đăng ký: tạo tài khoản và bắt đầu tiến trình.
  • Xác thực email: xác nhận email đăng ký bằng cách click vào đường dẫn trong Inbox.
  • Tạo website: bạn đã hoàn tất mọi thủ tục để có website cho riêng mình.

UltimateFreeHost

13 web hosting miễn phí dành cho lập trình viên13 web hosting miễn phí dành cho lập trình viên

Như tên gọi, UltimateFreeHost cung cấp Disk Space, băng thông vô hạn và không giới hạn tài khoản email. Người dùng có thể tạo cơ sở dữ liệu MySQL vô hạn & Cpanel Access để quản lý tốt hơn. Ngoài ra UltimateFreeHost cung cấp Free Domain, Subdomain hoàn toàn free, không giới hạn. Bạn cũng không cần viết code để tạo website vì UltimateFreeHost có Zyro website builder, một tính năng phát triển miễn phí. Ngoài ra còn có embedded traffic booster để thu hút traffic trên website.

Webfreehosting

13 web hosting miễn phí dành cho lập trình viên

WebFreeHosting cung cấp shared hosting miễn phí với tốc độ server khá nhanh. Trang miễn phí Disk Space 1GB và 5GB băng thông. Người dùng có thể chuyển file lên đến 2MB và đảm bảo Uptime 99.9%. Để host, WebFreeHosting cho phép 1 domain và 3 subdomain. Ngoài ra họ cũng cung cấp Cpanel nâng cao và Web Based File Manager. Đối với Email thì có thể host 1 địa chỉ với Filter, SPAM protection, virus protection, …. 

BIZ.NF

13 web hosting miễn phí dành cho lập trình viên

Biz.nf cung cấp web hosting vừa nhanh và miễn phí từ năm 2008, 1GB Disk SPace và trao đổi dữ liệu 5GB mỗi tháng hoàn toàn miễn phí. Domain sẽ có cú pháp “.co.nf”

Build web trên Biz.nf không hiện ads và chạy 100% trên năng lượng tái tạo. Với 1 Free Hosting Plan người dùng có thể host 4 website (1 domain chính và 3 subdomain). 

50WEBS

13 web hosting miễn phí dành cho lập trình viên

50webs.com cung cấp website hosting miễn phí đáng tin cậy mà không “dính” banner quảng cáo nào, gồm 500MB Disk Space và 5GB data băng thông hàng tháng. Bạn có thể host 10 domain mỗi tài khoản, và tạo đến 100 tài khoản email khác nhau. 50Webs khá phù hợp cho các beginner đấy.

Freehosting.com

13 web hosting miễn phí dành cho lập trình viên

Những tính năng mà Freehosting mang lại sẽ không tìm thấy ở các công ty web khác, khi người dùng có thể tạo bất kỳ loại website nào hoàn toàn free, và được cung cấp đến 10GB Disk Space và băng thông vô hạn. Nền tảng hosting của họ tích hợp với Linux, PHP, APache, MYSQL, …

Trên Freehosting bạn có thể host 1 website và 0 subdomain, tạo được 1 tài khoản email và 1 MySQL database. Việc tạo website cũng không quá khó khăn với Website Builder với hơn 170 template có sẵn. Ngoài ra họ cung cấp thêm các database và tính năng khác nhau như:

  • MySQL database server
    • InnoDB storage engine
    • phpMyAdmin
    • Unlimited MySQL queries
    • Unlimited query time
  • Apache / PHP 7
    • .htaccess support
    • All Major Apache modules
    • All common PHP extensions
    • Complete PHP functions enabled
    • PHP Safe mode switched off
    • 60 seconds PHP execution time
    • 200 MB Max upload file size
    • 256 MB Max PHP memory limit

Ngoài ra bạn có thể mua thêm những tính năng khác ngoài những gì trang cung cấp miễn phí.

Free Hosting Eu

Tương tự như Biz.nf, Freehostingeu cung cấp 200MB Disk Space và 4GB data transfer mỗi tháng, ngoài ra còn có 2 website builder hoàn toàn miễn phí. Bạn có thể host 1 domain và 5 subdomains.

Awardspace

13 web hosting miễn phí dành cho lập trình viên

AwardSpace được biết đến khá rộng rãi và free cho hầu hết các cách dùng, có thể host đến 4 website một tài khoản miễn phí và được đảm bảo mạng uptime lên đến 99.9%. 

Những tính năng của Awardspace:

  • Băng thông – 5GB
  • Disk Space – 1000MB
  • Zacky Website Builderq
  • Kích hoạt tài khoản nhanh chóng
  • Free PhpMyadmin Access
  • Hỗ trợ Full MYSQL Database
  • 100% Ad-Free
  • Hỗ trợ 24/7 

TopDev via real.tips

Tham khảo thêm các vị trí tuyển dụng ngành CNTT lương cao tại Topdev

Google Maps và React

Nhúng Google Maps vào web site bình thường thì quá sức đơn giản, để sử dụng với React Js thì hơi vụng công một chút.

Để sử dụng Google Maps API, ta chỉ cần load đoạn js từ googleapis, chèn thêm một cái div với id là map chằng hạn.

<!DOCTYPE html>
<html>
  <head>
    <title>Basic Google Map on a web page</title>
  </head>
  <body>
    <div id="map"></div>
    <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&"></script>
  </body>
</html>

 

Đoạn script của google sẽ được load sau khi có static DOM, cái <div id='map' /> lúc đó đã tồn tại và có thể được sử dụng thoải mái bởi google maps api.

Việc làm React lương cao không cần kinh nghiệm

Nhưng mà trong React JS thì DOM được render và re-render từ virtual DOM, một file html của app React JS thường là chỉ có thế này

<!DOCTYPE html>
<html>
  <head>
    <title>Simple React app</title>
  </head>
  <body>
    <div id="app"></div>
    <script src="js/app.js"></script>
  </body>
</html>

 

Tức là nếu làm như cách bình thường ở trên thì cái <div id='map' /> chưa hề tồn tại trên xã hội.

Load bất đồng bộ (Asynchronous Loading)

Cả hai đoạn script React và Google maps đều phải tốn thời gian để load, chúng ta phải đảm bảo Google Map chỉ được tạo ra sau khi React app đã khởi tạo và render DOM xong. Thoạt nhìn thì dùng asyn google map sẽ là một giải pháp.

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"
        async defer></script>

 

Chúng ta thêm asyn và defer để load đoạn googleapis này sau cùng, đồng thời thêm hàm callback sau khi load xong. Nếu initMap là một global function thì ta có thể gọi nó bên trong React Component

function initMap() {
  map = new google.maps.Map(document.getElementById('map'), { ... });
}

 

Buồn thay! Không chạy đâu các bạn ạ. Ngay cả khi Google Maps chỉ được load sau khi React được load, không có nghĩa là toàn bộ cây DOM đã được mount và render khi thực thi hàm callback.

Ok, chúng ta cần giải pháp tốt hơn. Về cơ bản

chúng ta muốn load đoạn script của google ngay khi component có sử dụng đến google api được mounted

componentDidMount {
    // trỏ global function window.initMap này vào hàm initMap của component để thằng google có thể  gọi trong hàm callback
    window.initMap = this.initMap;

    // chèn ngay đoạn js của googleapis cho anh xài ngay.
    loadJS('https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap')
}

initMap = () => {
    map = new google.maps.Map(this.refs.map.getDOMNode(), { /* các options khác*/});
}

render {
    return (
        <div>
            <div ref="map" style="height: '500px', width: '500px'"><⁄div>
        <⁄div>
    );
}

// hàm này để chèn thêm <script /> sau khi gọi
function loadJS(src) {
    var ref = window.document.getElementsByTagName("script")[0];
    var script = window.document.createElement("script");
    script.src = src;
    script.async = true;
    ref.parentNode.insertBefore(script, ref);
}

 

Để ý là ta thêm ref='map' để trỏ tới đúng cái div sử dụng để đưa vào cho Google Map constructor bằng hàm this.refs.map.getDOMNode() ngay khi DOM đã render.

Vậy là xong. Google Map đã có thể hoạt động trơn tru với React Component, đúng hơn là với Virtual DOM.

Tác giả: klaasnotfound Link bài gốc: http://www.klaasnotfound.com/2016/11/06/making-google-maps-work-with-react/

TopDev via Vuilaptrinh

Xem thêm các vị trí tuyển nhân viên it gấp tại đây

Sửa lỗi scroll với fixed header bằng CSS

Giải quyết issue với fixed header và scroll đến một element bằng hashtag

Khi sử dụng hashtag # cho attribute href, trình duyệt sẽ scroll tới element có id tương ứng section-two. Đây là một tính năng từ thời trình duyệt mới ra đời.

<a href="#section-two">Section Two</a>

 

Nhưng một khi chúng ta thêm một element với position: fixed, như header, vị trí scroll đến sẽ ko còn đúng nữa, nó vẫn scroll tới element đó, nhưng giờ nó có thể bị che bởi element đang set fixed.

Có rất nhiều cách để giải quyết vấn đề này trước đây, như thêm vào một đoạn padding vào element, hoặc dùng một đoạn javascript để handle, có tất cả 5 cách để giải quyết con issue này.

Fixed Header, Page Links

Giờ đây chúng ta có cách hoàn toàn mới chỉ với css

Sử dụng 2 thuộc tính mới là scroll-padding và scroll-margin

body {
  scroll-padding-top: 70px;
 /* giá trị chiều cao của header */
}

 

Hiện tại cái này chỉ chạy tốt trên trình duyệt dùng Chromiu

TopDev via Vuilaptrinh

Lập trình viên làm gì khi Corona hoành hành: ở nhà học tiếng Anh lập trình theo phong cách “fast and furious”

Có nhiều người luôn thắc mắc làm gì với nghề này để có mức thu nhập cao hơn và có bước tiến thân cao hơn trong nghề. Người thì lựa chọn cày ngày cày đêm, chạy từ dự án này sang dự án khác; người thì “đi tìm đường cứu thân”, sang một đất nước khác để có cơ hội cao hơn. Nhưng rồi lại gặp khó khăn lớn về ngôn ngữ, đặc biệt là tiếng Anh. Tự lúc nào nỗi sợ học tốt tiếng Anh lập trình đã làm rào cản khiến lập trình viên không dám mơ lớn, ngôn ngữ máy tính mình còn học được mà huống chi ngôn ngữ loài người nhỉ :)))

TÌNH TRẠNG CHUNG 

Bạn sẽ rất ngưỡng mộ khi bắt gặp ai đó xì xồ xì xào nói tiếng Anh với người nước ngoài và luôn tự nhủ mình cũng sẽ nói được nếu mình chăm luyện tiếng Anh. Và rồi tức tốc bạn về nhà ngay, lên kế hoạch cụ thể cho bản thân, google search thần tốc các mẹo học tiếng Anh, ghi ghi chép chép, note dán đầy phòng. Chưa kể thấy người ta chia sẻ tài liệu nào hay thì liền download về đến nỗi chật cả máy, và còn rất nhiều ti tỉ cách khác để bạn tự học được tiếng Anh. Nhưng rồi một ngày đẹp trời, chú lười đến rủ rê bạn đi chơi vài hôm, xem phim, cà phê trà sữa với bạn bè, lâu dần bạn lại bỏ xó xấp tài liệu kẹt trong máy và tờ note dính bụi trên tường. Và rồi vòng lặp cứ thế lại diễn ra. 

Bạn đừng quá lo, không chỉ có mình bạn mà đó là tình trạng chung của mọi người luôn rồi, kể cả mình – người đang gõ từng dòng chữ bài viết này. Mình may mắn đã thức tỉnh sớm và chia sẻ đến mọi người một số cách tự học tiếng Anh, nếu bạn đang đọc bài viết này có nghĩa bạn cũng đang may mắn lắm đấy *cười* 

Tiếng Anh là công cụ tốt nhất hiện nay để giao tiếp với mọi người. Nhiều người học tiếng Anh cảm thấy lo lắng, do dự về việc tự học. Sự thật là, internet không chỉ là nguồn tốt nhất để bạn học tiếng Anh, mà còn là cách dễ nhất để tự học bất cứ khi nào và bất cứ đâu bạn muốn. 

Tốt nhất là bạn nên học theo cách riêng của bản thân mình mà không cần phải làm theo lời khuyên của ai khác, hãy bớt phụ thuộc vào ai đó. Trong phim “The Karate Kids”, ông Parker đã nói với cậu bé rằng: “Võ thuật nằm trong chính những hành động hằng ngày của chúng ta”. Tiếng Anh cũng vậy ! Bạn thích nghe nhạc, bạn thích xem phim, bạn thích đọc blog, bạn thích nghe radio hoặc bất cứ gì bạn muốn, mọi thứ như vậy đều giúp bạn học tốt tiếng Anh. Bạn hãy để việc tự học tiếng Anh là điều làm bạn cảm thấy thoải mái, chứ không phải là gánh nặng (hồi nhỏ đã rất ám ảnh việc học để ba mẹ tự hào, để ba mẹ vui rồi, bây giờ lớn bạn không cần phải bắt ép bản thân như vậy nữa). 

Để có thể tự thân vận động được bạn hãy cho bản thân một lý do thật sự lớn để học tiếng Anh. 

Bước 1: TÌM MỘT LÝ DO DUY NHẤT KHIẾN BẠN PHẢI HỌC TIẾNG ANH 

Khi đọc đến đây bạn sẽ nghĩ ra cho mình được rất nhiều lý do nhỉ? Nào là, vì mình muốn được đi nước ngoài này, muốn được tỏ ra bảnh tỏn khi ra phố nói tiếng Anh như gió, vì nhỏ ghệ giỏi tiếng Anh nên mình phải đu theo, ty tỷ lý do. Nhưng bạn hãy tìm một lý do duy nhất trong hàng tá lý do đó, đó phải là lý do quan trọng nhất. 

Tại sao lại là quan trọng nhất, vì nếu lý do đó không quan trọng thì bạn sẽ chẳng có động lực nào để học tốt tiếng Anh (nếu bạn có lỡ sa ngã lười biếng). Lý do quan trọng nhất giống như là kim chỉ nam để bạn hướng theo, cũng giống như là cái neo để giữ bạn lại ý. 

Vậy làm sao để xác định được lý do quan trọng nhất? Cũng đơn giản thôi, đặt lý do và mục tiêu cuộc sống, nếu song song thì bỏ qua, còn nếu cắt nhau thì đó là lý do quan trọng nhất. 

Sau khi xác định được “cái neo”, muốn thuyền đi xa phải có thuyền trưởng chứ.. (từ đây tôi mạn phép ví việc học tốt tiếng Anh như con thuyền nhé !) ý tôi ở đây là bản kế hoạch chi tiết cụ thể để bạn dễ dàng vẽ ra lộ trình học tiếng Anh ấy mà. 

Bước 2: LẬP BẢN KẾ HOẠCH CHI TIẾT CỤ THỂ NHỮNG GÌ BẠN MUỐN LÀM BẰNG TIẾNG ANH 

Việc bạn lập kế hoạch này hãy dựa trên mục tiêu cuộc sống và lý do quan trọng phía trên. Những mục tiêu trong bản kế hoạch này nên nặng hơn trình độ hiện tại của bạn, vì nếu như bạn lập những mục tiêu rất dễ hoàn thành thì bạn rất khó để cải thiện tiếng Anh. Từng mục tiêu trong bản kế hoạch càng chi tiết càng tốt, não chúng ta vốn đã lười suy nghĩ nên bạn liệt kê càng cụ thể thì bản thân sẽ càng có trách nhiệm hơn, và quan trọng là hãy ghi bằng tiếng Anh cho bản kế hoạch này nhé. 

Ví dụ 1 : bạn nên lập kế hoạch như sau: 

  • Within 8 months, I want to be able to read and understand any article in the programming document. (Tôi muốn đọc và hiểu được bất kì bài viết nào của tài liệu lập trình trong vòng 8 tháng tới)
  • Within 6 months, I want to score at least 6.0 on the IELTS English exam so I can apply and be accepted to an exchange program (Trong vòng 6 tháng, tôi muốn đạt ít nhất 6.0 trong các bài kiểm tra IELTS, để tôi có thể đăng ký tham gia chương trình trao đổi quốc tế)
  • Within 3 months, I want to be able to talk with English speakers in social situations about everyday topics such as sports, music, films, travel and food. (Trong vòng 3 tháng, tôi muốn nói chuyện với người bản xứ về các chủ để hằng ngày trong xã hội, như thể thao, âm nhạc, phim ảnh, du lịch và thực phẩm)

Bạn có thể sắp xếp thời gian theo chiều ngược lại, miễn sao bạn nhìn vào thấy hợp lý. Mỗi người có cách sống và nguyên tắc riêng mà.

Ví dụ 2: bạn không nên lập kế hoạch như sau:

  • I want to speak English fluently (Tôi muốn nói tiếng Anh lưu loát)
  • I want to go to university in another country (Tôi muốn học đại học ở nước ngoài)
  • Get a girlfriend/boyfriend who speaks English (Tôi muốn có bạn gái/bạn trai nói tiếng Anh tốt)

Kế hoạch quá chung chung, rất dễ gây nhàm chán, không có sự ràng buộc nào cho bạn và bạn cũng sẽ không có lý do nào giúp níu kéo bạn trong việc học tốt tiếng Anh. 

Nếu bạn có giới hạn thời gian, thì bạn có thể đánh giá sự tiến bộ của bạn trong quá trình học và tìm hiểu xem bạn có cần thay đổi thói quen để đáp ứng mục tiêu của mình không. Mỗi mục tiêu tốt đều có thời hạn rất rõ ràng.

Neo có rồi, thuyền trưởng có rồi, bạn cần phải có thuyền thì mới khởi hành ra khơi được. 

Bước 3: TÌM TÀI NGUYÊN HỌC TIẾNG ANH 

Bước này rất quan trọng, là chìa khóa giúp bạn học tiếng Anh nhanh chóng. Nếu như trình tiếng Anh của bạn chỉ ở mức cơ bản hoặc trung cấp, thì đừng nên cố gắng đọc những bài viết trên trang The Verge (bật mí là nó sẽ làm mất động lực ngay vì nó khá khó so với trình độ hiện tại của bạn, toàn thuật ngữ chuyên ngành mà thôi). Thay vào đó, bạn có thể nghe những câu chuyện tin tức tiếng Anh rõ ràng, dễ hiểu trên DZone, NETTUTS, Web Designer Wall, và một số trang web khác dành cho việc học tiếng Anh lập trình  

Hãy chắc chắn rằng các nguồn tài nguyên học tiếng Anh này không quá dễ, vì nếu như bạn học những thứ dưới level hiện tại sẽ dễ khiến bạn nản và (có thể) sinh ra chứng tự mãn, nên hãy chọn nguồn học phù hợp với bản thân nhưng không quá khó. Nếu bạn là một người được nói tiếng Anh, việc đọc sách truyện thiếu nhi hoặc Wikipedia bằng các article tiếng Anh đơn giản sẽ khiến bạn cảm thấy tự tin hơn, và còn làm phong phú vốn từ, cấu trúc nữa. Bạn thực sự có học tiếng Anh không nếu như chỉ thấy những từ đã biết. 

Bạn hãy lựa chọn những bài viết mà bạn lướt qua có thể hiểu ý tác giả muốn nói nhưng cũng đủ khó để bạn phải tra cứu nhiều từ nếu bạn muốn hiểu chi tiết tường tận. Hãy cứ tìm kiếm, hãy cứ dại khờ :))) cho đến khi tìm được nguồn tài liệu phù hợp với trình độ của bạn. 

Có một lưu ý nhỏ trong này đó là hãy tìm nguồn tài liệu match với mục tiêu của bạn 

Xem phim, show truyền hình 

Chắc chắn rằng mọi thứ bạn tìm kiếm đều gần với mục tiêu của bản thân. Nếu mục tiêu của bạn là nói chuyện, giao tiếp tiếng Anh như người bản địa, thì bạn nên xem phim hoặc các show truyền hình (nhưng phải bằng tiếng Anh nha :D). Lúc đầu chắc hẳn sẽ gặp nhiều khó khăn, không sao đừng quá lo, bạn có thể bật phụ đề lên để vừa nghe được và cũng vừa biết được cấu trúc câu, thành ngữ và cụm từ đặc biệt (idioms and phrases) trong tiếng Anh. Khi bạn đã quen thuộc hơn và hiểu những gì diễn viên nói thì hãy xóa phụ đề và xem lại bộ phim một lần nữa để kiểm tra khả năng hiểu tiếng Anh của bạn. Đừng chán khi phải xem lại nhiều lần, hãy chọn bộ phim mà bạn cảm thấy hứng thú, tò mò về nó, mỗi khi bạn xem lại biết đâu được bạn lại học được bài học nào đó. 

Bản thân mình thì thích xem các thể loại hack não (càng khó hiểu càng tốt), bạn nào như mình thì có thể xem Inception, hoặc The Prestige (nếu có xem xong rồi thì cho mình biết cảm nhận như nào nha, với mình thì thấy đã lắm :D). Hoặc thể loại tình cảm, mình gợi ý phim Me before you; Love, Roise;…. bla bla, bạn cứ lên google search nhiều lắm. 

Ngoài ra, có một cách khác để bạn hiểu tường tận bộ phim hơn. Tưởng tượng ra sao nếu một ngày cầm trên tay kịch bản của các bộ phim bom tấn, như Avengers; Parasite, The Internet Movie Script Database (IMSDb) có một danh sách các kịch bản bộ phim mà bạn tha hồ chọn, đơn giản chỉ cần tìm kiếm bất kỳ bộ phim nào đó và đọc cùng lúc khi bạn xem phim, một trải nghiệm thú vị mới lạ ha :))

Xem video Youtube 

Ngoài xem phim ra thì có ty tỷ thứ trên Youtube, nhưng hãy search keyword bằng tiếng Anh thì mới ra nhiều nguồn được nhé! Bạn cũng có thể xem các cuộc phỏng vấn và đánh giá trên youtube, sẽ giúp bạn làm quen với tiếng Anh đàm thoại và cách bạn giao tiếp với người khác như thế nào. 

Tôi gợi ý nho nhỏ, nếu bạn mệt mỏi với việc xem, học mọi thứ bằng tiếng Anh thì bạn nên seach một vài video tiếng Việt nhưng đúng với công việc hiện tại của bạn (như kênh youtube TopDev TV chẳng hạn), vừa thư giãn vừa update kiến thức

  13 kênh Youtube lập trình tiếng Việt giúp bạn trở thành Fullstack developer

Nghe nhạc

Chán xem phim thì âm nhạc là lựa chọn giúp bạn vừa thư giãn vừa học tiếng Anh hiệu quả. Thực tập với các bài hát trending nổi tiếng thì tốt hơn vì bạn luôn nghe chúng ở bất cứ không gian nào, trong xe hơi, trong tiệm tạp hóa, hay trung tâm thương mại (vì chúng không phải là nhạc đặc thù nên phù hợp với mọi hoàn cảnh). Bạn nên tránh nghe rock và rap vì lời bài hát thường mù mờ, tiết tấu nhanh, khó nghe

Kiểm tra ngữ pháp tiếng Anh bằng các câu đố trực tuyến

Khi bạn tự học, một vấn đề xảy ra là bạn có thể bỏ lỡ những lỗi và sai sót mà bạn mắc phải. Một cách dễ dàng để tự kiểm tra là làm các câu đố tiếng Anh trực tuyến. Những câu đố này sẽ kiểm tra ngữ pháp, xây dựng câu dễ dàng hơn.

Chat, tám chuyện với người nước ngoài 

Trò chuyện với bạn bè trực tuyến là một cách thú vị để tự học tiếng Anh, nó khác với việc nói chuyện với giáo viên, hoặc học trên lớp, hoặc thậm chí sử dụng tiếng Anh tại nơi làm việc vì nó thoải mái, và ngôn từ dễ sử dụng. Trò chuyện là một cách tuyệt vời để học tiếng Anh vì bạn có thể thực hành những gì bạn đã học theo cách giản dị, không căng thẳng. Thông qua trò chuyện trên bàn phím, bạn có thể kiểm tra các lỗi ngữ pháp trước khi nhấn nút Enter. Ngoài ra, việc bạn bè của bạn nói tiếng Anh với bạn là động lực thúc đẩy hơn cho bạn. Bạn không chỉ có thể chứng minh với họ rằng tiếng Anh của bạn ngày càng tốt hơn, mà bạn còn cảm thấy thỏa mãn hơn khi biết rằng bạn có thể nói tiếng Anh thoải mái với bạn bè bất cứ lúc nào.

Đọc e-book, báo, tạp chí online 

Đọc cũng quan trọng như nghe khi học tiếng Anh. Đọc và nghe vừa làm sắc nét tâm trí vừa rèn luyện bạn suy nghĩ bằng tiếng Anh.

Những người nói tiếng Anh không phải là người bản ngữ luôn phải dịch tiếng Anh trong tâm trí, điều này gây ra sự chậm trễ trong phản ứng. Tuy nhiên, nếu tâm trí được đào tạo để suy nghĩ bằng tiếng Anh điều này giúp dễ dàng trong việc hiểu và nói ngôn ngữ. Bạn càng đọc nhiều, bạn càng tiếp xúc nhiều hơn với cấu trúc câu tiếng Anh, từ vựng mới có nghĩa là bạn có rất nhiều câu để lựa chọn khi bạn bắt đầu nói tiếng Anh.

Internet là một kho tàng sách điện tử, bài báo và tạp chí tiếng Anh. Tìm một tài nguyên với một chủ đề mà bạn thực sự quan tâm. Mà không chỉ Internet, Google là một kho tàng không đáy nữa, “dân ta phải biết sử ta, nếu mà không biết thì tra google”, bạn muốn gì cứ lên google là có tất, chỉ có điều bạn có kỹ năng search google hay không thôi :))) 

  Cách tìm kiếm nâng cao với Google

Viết ra những gì bạn nghĩ 

Nó không phải là một bài báo được xuất bản trực tuyến, bạn chỉ cần bắt đầu với những điều cơ bản diễn ra xung quanh, có thể hiểu như là một nhật ký hằng ngày (daily diaries) vậy ý. Viết tác phẩm của riêng bạn kết hợp tất cả việc học của bạn với nhau với tất cả những gì bạn biết về ngữ pháp tiếng Anh, từ vựng và hiểu biết tổng thể.

Sau khi viết, hãy tự kiểm tra lại xem có lỗi nào không. Để làm điều này, tốt nhất là đưa những gì bạn vừa viết vào một tệp để bạn có thể sử dụng các chương trình kiểm tra ngữ pháp để xác định vị trí lỗi.

Có nguồn học xong xuôi hết rồi thì bước cuối cùng này cũng là bước quan trọng lắm đấy. 

Bước 4: THỰC HÀNH MỖI NGÀY

Vì sao lại thực hành mỗi ngày, vì những lý do sau đây: 

  • Tạo động lực: Nếu bạn làm điều gì đó mỗi ngày, nó sẽ trở thành thói quen. Một khi bạn tạo thói quen, bạn sẽ có động lực để tiếp tục thói quen đó.
  • Tiết kiệm thời gian: Khi bạn chỉ học một hoặc hai lần một tuần, bạn sẽ quên rất nhiều điều mới bạn đã học trong buổi học trước. Vì vậy, bạn phải lãng phí rất nhiều thời gian có giá trị của mình để xem xét những thứ bạn đã học. Nếu bạn học mỗi ngày, tài liệu mà bạn đã học ngày hôm trước sẽ tươi mới trong tâm trí bạn, điều đó có nghĩa là bạn sẽ dành ít thời gian hơn để xem xét.

Lời nhắn nhủ: ĐỪNG BỎ CUỘC

Tôi biết bạn có thể học tiếng Anh hiệu quả, thậm chí là học tốt hơn cả tôi (tôi đã già rồi !). Làm sao tôi biết ư? Bởi vì hàng triệu và hàng triệu người trên khắp thế giới đã chứng minh rằng điều đó xảy ra được. Bạn càng luyện tập, càng mắc lỗi, càng nói, bạn càng nhanh chóng thông thạo tiếng Anh. Vậy tại sao không bắt đầu ngay hôm nay?

Chúc bạn thành công trên con đường học tốt tiếng Anh này !

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

Tìm việc IT lương cao, đãi ngộ tốt trên TopDev ngay!

Cách làm các slide và các hiệu ứng hover do JavaScript và CSS tạo ra

Làm sao để sử dụng previousElementSibling để biết được position của phần tử đó của mảng, ngoài ra còn dùng bằng jquery để code (không chuyên sâu lắm);

Khi code previousElementSibling này mục đích chính của nó là phục vụ cho code slide và các sự kiên hover mà nhiều phần tử hoạt động, theo mình nó vẫn là quan trọng với 1 số html devolop

Khi code cái này chúng ta cần biết được cái gì là phần tử đang hoạt động, để tìm ra cái thằng đứng sau ngay nó

<div class="one_team  run">
                    <div class="row" style="position: relative;">
                        <div class="one_people col-sm-4">
                            <img src="images/team-img1.jpg" alt="" srcset="" class="imgs_vt2">
                            <div class="bolds">
                                <b class="bold_vt2">MARY,CEO</b>
                            </div>
                            <p class="text_vt2">Lorem ipsum dolor sit amet consectetur, adipisicing elit.</p>
                        </div>
                        <div class="one_people col-sm-4">
                            <img src="images/team-img2.jpg" alt="" srcset="" class="imgs_vt2">
                            <div class="bolds">
                                <b class="bold_vt2">MARY,CEO</b>
                            </div>
                            <p class="text_vt2">Lorem ipsum dolor sit amet consectetur, adipisicing elit</p>
                        </div>
                        <div class="one_people col-sm-4">
                            <img src="images/team-img3.jpg" alt="" srcset="" class="imgs_vt2">
                            <div class="bolds">
                                <b class="bold_vt2">MARY,CEO</b>
                            </div>
                            <p class="text_vt2">Lorem ipsum dolor sit amet consectetur, adipisicing elit.</p>
                        </div>
                    </div>
                </div>

                <div class="one_team">
                    <div class="row">
                        <div class="one_people col-sm-4">
                            <img src="images/team-img4.jpg" alt="" srcset="" class="imgs_vt2">
                            <div class="bolds">
                                <b class="bold_vt2">MARY,CEO</b>
                            </div>
                            <p class="text_vt2">Lorem ipsum dolor sit amet consectetur, adipisicing elit.
                            </p>
                        </div>
                        <div class="one_people col-sm-4">
                            <img src="images/team-img5.jpg" alt="" srcset="" class="imgs_vt2">
                            <div class="bolds">
                                <b class="bold_vt2">MARY,CEO</b>
                            </div>
                            <p class="text_vt2">Lorem ipsum dolor sit amet consectetur, adipisicing elit</p>
                        </div>
                        <div class="one_people col-sm-4">
                            <img src="images/team-img6.jpg" alt="" srcset="" class="imgs_vt2">
                            <div class="bolds">
                                <b class="bold_vt2">MARY,CEO</b>
                            </div>
                            <p class="text_vt2">Lorem ipsum dolor sit amet consectetur, adipisicing elit.</p>
                        </div>
                    </div>
                </div>

                <div class="one_team">
                    <div class="row">
                        <div class="one_people col-sm-4">
                            <img src="images/team-img7.jpg" alt="" srcset="" class="imgs_vt2">
                            <div class="bolds">
                                <b class="bold_vt2">MARY,CEO</b>
                            </div>
                            <p class="text_vt2">Lorem ipsum dolor sit amet consectetur, adipisicing elit</p>
                        </div>
                        <div class="one_people col-sm-4">
                            <img src="images/team-img8.jpg" alt="" srcset="" class="imgs_vt2">
                            <div class="bolds">
                                <b class="bold_vt2">MARY,CEO</b>
                            </div>
                            <p class="text_vt2">Lorem ipsum dolor sit amet consectetur, adipisicing elit</p>
                        </div>
                        <div class="one_people col-sm-4">
                            <img src="images/team-img4.jpg" alt="" srcset="" class="imgs_vt2">
                            <div class="bolds">
                                <b class="bold_vt2">MARY,CEO</b>
                            </div>
                            <p class="text_vt2">Lorem ipsum dolor sit amet consectetur, adipisicing elit.</p>
                        </div>
                    </div>

Trong cái souce code này nó có 3 cục cha là “one_team” đây là 3 cục mà dùng để chuyển slide, khi muốn có 1 slide chúng ta phải cho tất cả phần tử là

position: absolute;
width:100%;
height:100%;

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

Những kinh nghiêm thú vị hơn là khi ta code mấy phần tử này ,chúng ta nên để nó là:

opacity : 0;
visibility: hidden;

 

Cho tất cả biến mất đi khi đó để nó hoạt động, bạn muốn cái phần tử mẹ nào hoạt động thì cho một cái class gì gì đó và vào css set cho nó là:

opacity : 1;
visibility: visible;

Nó có thể giảm tối thiểu việc hiệu ứng slide, vậy là xong cái css việc còn lại là chỉ cần set Jquery (or JavaScript) sao cho theo ý định của mình.

Nếu ai muốn dùng kiểu button để điều chỉnh các slide thì mình sẽ đưa ra ngay đây.
Vẫn tiếp tục với cái souce code đau não lúc nãy thì nó sẽ có 3 cái btn tượng trưng cho 3 cái phần tử trong slide.
Nó như thế này:

 <button class="btn btn-primary btns-vt2"></button>
                <button class="btn btn-primary btns-vt2"></button>
                <button class="btn btn-primary btns-vt2"></button>

 

Thường khi dùng btn của slide ta thường đặt tên class giống nhau cho dễ xử lý. Để xử lý cái này ta cần biết cái vị trí btn trong cái arr mà khách hàng click vào là bao nhiêu ; bằng cách như thế này: (JavaScript and Jquery)

var btn = document.getElementsByClassName("btns-vt2");
    for(var i =0 ; i < btn.length ;i++){
        btn[i].onclick=function name(params) {
            var is=0;
            var this_slide=this;
            for( is = 0 ; this_slide=this_slide.previousElementSibling;is++){
          //cái này chính là cái thuật toán tính vị trí đấy
         }

            for( us = 0 ; us < $(".one_team").length;us++){ 
          // vòng này thì nó lại khác trước khi mà click vào thì phải 
           xóa all các phần tử trong đó
                $(".one_team").eq(us).removeClass("run");
            }
            $(".one_team").eq(is).addClass("run");
                    }
    }

 

Và nếu theo Jquery thì mình làm theo thuật toán của mình là như sau (cái này hơi dài đây là một souce code khác nên các bạn cố hình dung nhé!!)

 $(".one_people").hover(function name (params) {
        var stt=0;  
        var te= $(this);
        for(var is=0; is<$(".one_people").length;is++){
            if($(".one_people").eq(is).html()==te.html()){
                stt=is;
            }
        }
       $(".imgs_vt2").eq(stt).addClass("gout");  
        $(".text_vt2").eq(stt).addClass("over");
        $(".imgs_vt2").eq(stt).removeClass("ungout");  
        $(".text_vt2").eq(stt).removeClass("unover");

 

Cái này là một ví dụ cho cái hover mà nhiều phần tử chuyển động như mình nói trên ấy sau đó bạn thích add gì thì add, theo mình để các hiệu ứng đẹp hơn thì cần thuần thạo cái animation ;

.ungout{
    position: relative;
    transition: 0.4s;
    top: 0px;
    animation: ungo_top 0.5s;
    opacity: 1;
}
@-webkit-keyframes ungo_top{
    to{top: 0px;position: relative;opacity: 1;}
    from{top:-100px; position: relative;opacity: 1;}

Thế nhé, qua bài viết trên mong các bạn sẽ có thêm chút kiến thức cho mình!

TopDev via Tapchilaptrinh

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

Hiểm nguy rình rập khi dùng toán tử + trong javascript

hiem-nguy-rinh-rap-khi-dung-toan-tu-trong-javascript

Một toán tử phình phường có thể làm chúng ta điêu đứng

Như mọi thứ ngôn ngữ lập trình, ngôn ngữ toán học, Javascript dùng dấu + để thực hiện cộng giá trị. Tuy nhiên, vì là Javascript, anh có quyền không đi theo quy chuẩn chung, anh còn được dùng cho việc nối chuỗi

Nếu chúng ta dùng nó cho việc cộng số

const giaKhauTrangBinhThuong = 35000;
const doiGiaDichCovy = 300000;
const tienShip = 20000;
const chiPhiMuaHopKhauTrang = giaKhauTrangBinhThuong * doiGiaDichCovy + tienShip;

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

Chúng ta dùng nó cho việc nối chuỗi

const ten = "Tui là An";
const nenLamGi = "Tui ở nhà cho Bình An";

const tuiLaAi = ten + ' & ' + nenLamGi;

Chúng ta sẽ có câu “Tui là An & Tui ở nhà cho Bình An”, mọi thứ hoạt động bình thường.

Thí dụ bạn lỡ viết thế này thì sao

const seRaSao = 9 + '1';

Khi có 2 giá trị khác kiểu, nó sẽ ưu tiên kiểu giá trị mạnh hơn, là kiếu string nên kết quả chúng ta nhận là “91” chữ không phải 10

Điều đúc kết ở đây là gì, hễ chúng ta muốn cộng 2 con số lại, chuyển nó về giá trị số Number(ten_bien) trước cho chắc.

Bài viết gốc tại Vuilaptrinh

Tham khảo thêm các tin tuyển dụng việc làm IT trên TopDev

Mãi phàn nàn – than vãn về công ty, xu hướng chung của người bắt đầu công việc?

Một câu hỏi nhỏ dành cho bạn: Bạn có thường hay than vãn, tâm sự về tất tần tật những chuyện buồn vui trên công ty với các hội anh em/bạn bè của mình không? Khỏi nói cũng biết, tất nhiên là có rồi, bản thân TopDev cũng nghe nhiều phản hồi thú vị xoay quanh môi trường nhân sự đấy!

Niềm vui có, nỗi buồn có, khen chê đều có. Tuy nhiên, những gì TopDev ghi nhận được là những người mới bắt đầu đi làm hoặc đi làm chưa lâu, họ có xu hướng chê công ty của mình nhiều hơn là đánh giá cao tiềm năng của công ty:

  • Công ty dùng công nghệ cũ xì khiến việc vận hành không hiệu quả. Công ty gì phúc lợi kém quá, lại hay kì kèo.
  • Đồng nghiệp thì ba gai đủ chuyện. Sếp thì thiếu quan tâm thậm chí không hề hiểu nhân viên. 
  • Công việc dồn dập và tình trạng nước đến chân mới nhảy liên tục diễn ra.
  • Đôi khi công việc quá nhàn hạ, không rõ định hướng và bản thân nhân viên không phát triển được.  

Nói chung là có vô vàn thứ để chê. Và TopDev đang thuật lại những suy nghĩ của một nhóm người đang trong giai đoạn tiếp cận môi trường mới. Thật ra, việc bạn là ai và làm gì, làm ở môi trường nào cũng đều có những ý nghĩa riêng cả. Liệu các bạn có thay đổi suy nghĩ của mình về các công ty không? Cùng TopDev xem hết bài viết nhé! 

  Top 5 website giúp thiết kế CV chuẩn format, đủ nội dung
  Viết thư xin việc đúng cách

Tập thích nghi là điều quan trọng

Tốt nghiệp một ngôi trường Đại học danh tiếng cùng tấm bằng cử nhân, bạn bắt đầu đi làm tại một công ty cũng có chút tiếng tăm. Rồi chuyện gì xảy ra tiếp theo. Bạn than phiền: Công ty gì lương thấp quá vậy, công việc thì thiếu sáng tạo mà suốt ngày cứ đòi hỏi nhân viên này nọ. 

Trải nghiệm đầu về chuyến hành trình chinh phục công việc mơ ước kết thúc khi bạn quyết định rời khỏi công ty. Rồi kế đến, bạn lại “nhập gia tùy tục” tại một công ty với quy mô lớn hơn. Giai đoạn đầu là những chuỗi ngày êm đềm đúng nghĩa. Tuy nhiên sau đó, bạn chợt nhận ra, bản thân mình lại tiếp tục chê công ty: 

1. Công ty gì lớnlương thưởng không có. Task thì nhiều – Deadline thì dí nhân viên mà lương OverTime tương ứng con số 0 tròn trĩnh 

2. CEO đúng là có tố chất nhưng ngược với lãnh đạo thì lúc nào cũng lãnh đạm với nhân viên

3. Lương thì thấp, làm lâu mà không được tăng lương nhiều

Tiếp tục vòng quay trải nghiệm, bạn lại “bay” sang một công ty khác. Ở đây lương cao hơn, trả đúng hạn, quá tốt rồi nhưng không, bạn lại than phiền chuyện khác:

  • Đồng nghiệp nhiều gì mà hơn thua, coi thường người khác, thiếu thân thiện 
  • Công ty gì cứ liên tục thay đổi yêu cầu, thích chỉ định và không lắng nghe tiếng nói của nhân viên
  • CEO phởn phơ và nhàn rỗi “đi dạo” vòng quanh giám sát nhân viên, ai mà tập trung làm việc được

Các bạn có nhận ra điều gì không? Việc các bạn chê trách hay than vãn về công ty của mình bắt nguồn từ những “viễn cảnh tươi đẹp” mà các bạn đã vẽ ra trước khi bắt đầu trải nghiệm cuộc sống của một nhân viên. Hãy nhớ rằng, công ty cũng giống như một xã hội thu nhỏ. Nơi đó bạn sẽ tiếp xúc nhiều người, nhiều cái mới hơn. Việc quan trọng nhất của bạn lúc này là học cách thích nghi với môi trường làm việc. Đồng thời, bạn hãy mang trong mình những suy nghĩ tích cực hơn, loại bỏ những định kiến, cảm xúc tiêu cực về công ty. Điều này giúp bạn tìm ra được ý nghĩa thật sự trong vấn đề trải nghiệm công việc.

Hãy khai thác những khía cạnh tích cực và chấp nhận một điều: Công ty nào cũng có vấn đề cả!

Việc bạn điều chỉnh suy nghĩ sẽ tạo ra những thay đổi lớn. Hãy thử nhìn vào những mặt tốt của công ty xem, biết đâu bạn sẽ biết thêm nhiều điều thú vị. 

Ngồi ngẫm nghĩ lại, bạn lại nhận ra công ty mình cũng có điểm tốt đấy chứ:

  • Cũng có đồng nghiệp vui tính, lại thông tin, giỏi chuyên môn IT và giúp đỡ mình nhiều
  • Công việc nhiều nhưng mình biết cách cân bằng, nắm được những phần core quan trọng. Môi trường cũng khá năng động giúp mình nhanh lên trình hơn 
  • Mình được chọn tham dự mấy khóa học đào tạo chuyên môn, tận mắt thấy những quy trình công nghệ hiện đại và còn được gặp gỡ nhiều nhân vật nổi tiếng là các chuyên gia hàng đầu trong lĩnh vực nhân sự IT nữa 

Một điều bạn nên biết là bất kỳ một công ty nào cũng có vấn đề cả. Điều quan trọng là bạn có tinh tế nhận ra được và chấp nhận nó hay không. Những vấn đề đó có thể xuất phát từ nhiều chiều và trở thành đặc tính chung của mọi quy mô tổ chức/doanh nghiệp. 

Như đã nói trước đó, vì là giai đoạn trải nghiệm công việc, bạn hãy học cách thích ứng sao cho phù hợp với môi trường. Bất kỳ ai cũng đều có những định hướng cụ thể để thăng tiến trong sự nghiệp và bạn cũng không ngoại lệ. Hãy tập trung phần mình và cố gắng tạo ra những giá trị. Về chuyện các vấn đề tồn đọng, nếu là một nhân viên có bản lĩnh thì việc giải quyết chúng chỉ còn là thách thức về thời gian đối với bạn mà thời.

Hãy biến thách thức thành cơ hội

Thay vì suy nghĩ về những điều tiêu cực, bạn hãy biến nó thành cơ hội để bạn thể hiện năng lực của mình:

  • Nếu quy trình không rõ ràng? Đừng lo, hãy chủ động kêu gọi và ngồi lại với team để thảo luận, đóng góp các ý kiến nhằm tạo ra một quy trình phù hợp hơn
  • Nhân sự thiếu kỹ năng cả về chuyên môn lẫn kỹ năng mềm? Bạn đừng chê nữa, hãy mở lòng giao tiếp với họ. Bạn có thể tìm hiểu những mong muốn của họ để rồi trình bày lại với nhà quản lý/lãnh đạo nhân sự. Biết đâu các đồng nghiệp đang chờ một người biết chủ động và không ngại thể hiện mình như bạn đấy
  • Nhân thấy hệ thống tổ chức chưa thật sự thích hợp? Chỉ đơn giản là bạn chia sẻ với các manager, leader, cùng họ phân tích và đề xuất những phương án mới, có tính khả thi hơn

Đấy! Khó khăn nào rồi cũng có cách giải quyết thôi, phải không nào! Thách thức được tạo ra để bạn thử sức và trải nghiệm mình. Cũng có thể nói thách thức chính là cơ hội. Vì thế, bạn nên tận dụng những thách thức để tạo ra những giá trị riêng cho bản thân mình. Việc chấp nhận các thách thức, thay đổi suy nghĩ tích cực hơn và học cách thích nghi linh hoạt với môi trường sẽ giúp bạn có những trải nghiệm tuyệt vời trong công việc của mình.

Lời kết:

Điều mấu chốt bạn cần nhớ là đừng áp đặt quá nhiều suy nghĩ của bạn về môi trường làm việc của công ty. Và cũng đừng so sánh công ty này với công ty khác. Mỗi công ty đều khác nhau và tất nhiên chúng đều có những vấn đề riêng khó thay đổi. Hãy thích nghi và giảm thiểu những xúc cảm tiêu cực để mỗi ngày làm việc đều có những niềm vui. Chung quy lại, mọi thứ đều do chính bạn, hãy nhìn nhận đúng đắn và hy vọng bạn sẽ lựa chọn cho mình một công ty phù hợp để đồng hành phát triển lâu dài. 

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

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

Giải thích Javascript Reactivity

giai-thich-javascript-reactivity

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

Rất nhiều thư viện Javascript như Angular, React, Vue sử dụng Reactivity, hiểu được reactivity là gì và cách nó chạy sẽ giúp nâng cao kỹ năng lập trình

Một ví dụ về Reactivity của Vue

<div id='app'>
  <div>Price: ${{ price }}</div>
  <div>Total: ${{ price * quantity }}</div>
  <div>Taxes: ${{ totalPriceWithTax }}</div>
</div>
var vm = new Vue({
  el: '#app',
  data: {
    price: 5.00,
    quantity: 2
  },
  computed: {
    totalPriceWithTax() {
      return this.price * this.quantity * 1.03
    }
  }
})

Ở đây khi chúng ta thay đổi giá trị của price, thằng Vue nó sẽ làm 3 thứ

  1. Cập nhập lại giá trị price
  2. Tính lại giá trị total
  3. Gọi lại hàm totalPriceWithTax và cập nhập lại giá trị

Thấy hết sức bình thường, nhưng đó KHÔNG PHẢI LÀ CÁCH CHẠY BÌNH THƯỜNG CỦA JAVASCRIPT

Ví dụ với javascript bình thường

let price = 5
let quantity = 2
let total = price * quantity // kết quả sẽ là 10
price = 20 // gán lại giá trị của price
console.log(`total is ${total}`)

Bạn hãy đoán xem kết quả log ra là mấy? Sẽ là 10 chứ không phải 40 đâu.

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

Vấn đề và giải pháp

Vấn đề là chúng ta cần phải lưu cái cách tính price * quantity này lại ở đâu đó, để chúng ta re-run cách tính này khi gọi lại total, nó sẽ không nên là biến số mà là thành hàm, thì khi đó nếu giá trị price hoặc quantity thay đổi chúng ta sẽ có kết quả total thay đổi theo.

Chúng ta cần một nơi để lưu phần code tính toán kiểu như vậy lại ở đâu đó, để khi price hoặc quantity thay đổi, chúng ta sẽ chạy lại tất cả những gì đã lưu

let price = 5;
let quantity = 2;
let total = 0;
let target = () => { total = price * quantity }

record(); // lưu lại đâu đó để re-run sau này

target(); //

Hàm record chúng ta sẽ implement nó như sau

let storage = []; // đưa toàn bộ các hàm muốn re-run vào mảng này

function record() {
  storage.push(target);
}
// hàm để chạy lại tất cả những thứ đã lưu trong store
function replay() {
  storage.forEach(run => run());
}

Giải pháp tổng quát hơn

Nếu đã nắm được ý tưởng chính để giải quyết bài toán ban đầu, giờ chúng ta sẽ hiện thực hóa nó bẳng observer pattern, tạo một class để quản lý những chuyện đó

class Dep {
  constructor() {
    // thay vì là starage, thiên hạ đã thống nhất lấy cái tên subscribers
    this.subscribers = []; 
  }
  depend() {
    if (target && !this.subscribers.includes(target)) {
      // chỉ thêm vào nếu chưa có hoặc không trùng
      thiss.subscribers.push(target);
    }
  }
  notify() {
    // run tất cả target, tên gọi khác là observer
    this.subscribers.forEach(sub => sub()); 
  }
}

Code lại ví dụ trên sử dụng class mới tạo này

const dep = new Dep();

let price = 5;
let quantity = 2;
let total = 0;
let target = () => { total = price * quantity }
dep.depend();
target();

console.log(total); // 10
price = 20;
console.log(total); // 10
dep.notify();
console.log(total); // 40

Chúng ta vẫn còn có thể nâng cấp đoạn code trên, thay vì

let target = () => { total = price * quantity }
dep.depend();
target();

… chúng ta đóng gói nó vào một watcher, sau đó chỉ cần gọi

watcher(() => {
  total = price * quantity
})

Implement cái function watcher này như bên dưới

function watcher(myFunc) {
  target = myFunc; // active target, target ở đây là global variable
  dep.depend(); // đưa target vào dependency
  target(); // gọi hàm target
  target = null; // reset
}

Tách Dep cho mỗi biến

Chúng ta sẽ muốn mỗi một biến có một Dep riêng, trước tiên ta đưa price và quantity thành property của data

let data = {price: 5, quantity: 2}

Chúng ta sẽ có các Dep khác nhau cho price và quantity

watcher phụ thuộc cả 2 biến

watcher(() => {
  total = data.price * data.quantity;
})

watcher chỉ phụ thuộc biến price

watcher(() => {
  salePrice = data.price * 0.9;
})

Chúng ta muốn khi giá trị price bị thay đổi, hàm dep.notify của price store sẽ được gọi

>> total
10
>> price = 20 // lúc này thằng notify của price sẽ được gọi liên luôn
>> total
40

Đọc thêm tài liệu về Object.defineProperty nếu chưa biết. Áp dụng nó trong ví dụ này

let data = {price: 5, quantity: 2}

let internalValue = data.price; // giá trị khởi tạo

Object.defineProperty(data, 'price', { // chỉ cho thằng Price Property
  get() {
    console.log('Em bị access');
    return internalValue;
  },
  set(newVal) {
    console.log('Em bị thay đổi');
    internalvalue = newVal;
  }
})
data.price // call get()
data.price = 20 // call set()

total = data.price * data.quantity;
data.price = 20;

Với cách này, chúng ta có thể chạy kèm một hàm nào đó khi giá trị price được get hoặc set. Với idea là như thế chúng ta tổng quát quá lên cho nhiều biến

let data = {price: 5, quantity: 2}

Object.keys(data).forEach(key => {
  let intervalvalue = data[key];
  Object.defineProperty(data, key, { // chỉ cho thằng Price Property
    get() {
      console.log('Em bị access');
      return internalValue;
    },
    set(newVal) {
      console.log('Em bị thay đổi');
      internalvalue = newVal;
    }
  })
})

total = data.price * data.quantity;
data.price = 20;

Tổng hợp các ý tưởng chính

total = data.price * data.quantity

Khi một đoạn code như vậy được chạy, nó sẽ get giá trị của price, chúng ta muốn thẳng price khi bị thay đổi hoặc gọi, nó sẽ re-run một function

  • Ở Get: nhớ dùm cái function này, bọn tao sẽ nhờ mày chạy lại
  • Ở Set: chạy cái function mày đã giữ hộ ấy, thay đổi giá trị luôn nhé

Và đây là toàn bộ code

let data = {price: 5, quantity: 2};
let target = null;

// Dep không thay đổi gì so với ở trên
class Dep {
  constructor() {
    // thay vì là starage, thiên hạ đã thống nhất lấy cái tên subscribers
    this.subscribers = []; 
  }
  depend() {
    if (target && !this.subscribers.includes(target)) {
      // chỉ thêm vào nếu chưa có hoặc không trùng
      thiss.subscribers.push(target);
    }
  }
  notify() {
    // run tất cả target, tên gọi khác là observer
    this.subscribers.forEach(sub => sub()); 
  }
}

// chạy qua từng data của property
Object.keys(data).forEach(key => {
  let intervalvalue = data[key];

  // mỗi em một Dep
  const dep = new Dep();

  Object.defineProperty(data, key, { // chỉ cho thằng Price Property
    get() {
      dep.depend(); // lưu hộ tao cái
      return internalValue;
    },
    set(newVal) {
      internalvalue = newVal;
      dep.notify();// re-run đi em
    }
  })
})

// watcher sẽ không còn gọi dep.depend nữa
function watcher(myFunc) {
  target = myFunc;
  target();
  target = null;
}

watcher(() => {
  data.total = data.price * data.quantity;
})

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

Tuyển dụng lập trình viên lương cao trên TopDev

3 lỗi javascript thường mắc phải làm ảnh hưởng perfomance

Bài viết dành cho những người nghiện tốc độ, nghiện cách viết ES6, cùng điểm qua 3 lỗi thường gặp dẫn đến ảnh hửởng performance trong Javascript.

1. loop qua một array

Chúng ta thử xem thời gian tiêu tốn cho việc loop qua 10k item trong array

  • for: ~10 microseconds
  • while: ~11 microseconds
  • forEach: ~77 microseconds
  • for-of: ~110 microseconds
  • reduce: ~113 microseconds

Nếu muốn tính tổng của một array thì sử dụng reduce là rõ ràng, tuy nhiên cái giá phải trả quá lớn. Vòng lặp mới nhất từ ES6 for-of cũng về áp chót. Như vậy cứ xài vòng for kinh điển, tuy cũ mà nhanh gấp 10 lần cái for-of

Tuyển dụng Javascript đãi ngộ tốt trên TopDev

2. Duplicate một array

Khi thế giới đang tồn thờ tư tưởng immutable function ( không sửa cái input khi cho ra output ), việc duplicate một input array là chuyện thường ngày ở huyện.

Chúng ta hãy xem kết quả tất cả các cách chúng ta có thể dùng để duplicate một array

  • [].concat(arr): ~366 microseconds
  • arr.slice(): ~367 microseconds
  • arr.map(x => x): ~469 microseconds
  • [...arr]: ~512 microseconds
  • Array.from(arr): ~1,436 microseconds

Như vậy 2 phương thức cũ như dưa mắm concat và slice vẫn dành chiến thắng, kiểu spread operation mới ES6 vẫn top cuối.

  Tại sao API của Facebook lại bắt đầu bằng một for loop?

3. Loop qua một object

  • for(let key in obj): ~240 microseconds
  • Object.keys(obj) sau đó for each: ~294 microseconds
  • Object.entries(obj) sau đó for of: ~535 microseconds

Ở hai cách làm bên dưới, do phải tạo thêm một mảng chứa key, rồi mới loop qua mảng này object nên nó chậm.

  JavaScript Arrays và Objects thật ra không khác gì sách và báo
Đừng mù quáng xài cách viết mới nếu không phù hợp với ứng dụng đang viết

3 JavaScript Performance Mistakes You Should Stop Doing </a

TopDev via Vuilaptrinh

Tham khảo các vị trí lập trình viên IT khác tại đây

Xử lý lỗi nếu có xảy ra trong Javascript

Tác giả: Lưu Bình An

Lỗi nếu có xảy ra, phải được xử lý hết tránh để chết nguyên ứng dụng. Điểm lại một vài cách xử lý lỗi trong javascript

Javascript error

throw new Error('khi có lỗi') sẽ tạo ra một object Error và dừng chạy.

Error object có 2 property có sẵn, 1 là message

const myError = new Error('Lỗi rồi nè');
console.log(myError.message);
// => Lỗi rồi nè

…cái thứ 2, rất quan trọng, là stack, nó sẽ cho ta history các phương thức và file đã gọi qua.

Error: please improve your code
 at Object.<anonymous> (/Users/gisderdube/Documents/_projects/hacking.nosync/error-handling/src/general.js:1:79)
 at Module._compile (internal/modules/cjs/loader.js:689:30)
 at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
 at Module.load (internal/modules/cjs/loader.js:599:32)
 at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
 at Function.Module._load (internal/modules/cjs/loader.js:530:3)
 at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
 at startup (internal/bootstrap/node.js:266:19)
 at bootstrapNodeJSCore (internal/bootstrap/node.js:596:3)

Nếu chúng ta không tự xử lý các trường hợp có lỗi, nó sẽ chết ngay chổ đó, để tránh tình huống này, tìm hiểu một số cách bắt lỗi

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

try…catch

const a = 4;

try {
  // b chưa được định nghĩa, nó sẽ báo lỗi
  console.log(b);
} catch (err) {
  console.error(err)
}

// vẫn chạy đến đây
console.log(a);

Nếu không để console.log(b) bên trong try..catch, nó sẽ không chạy đến đoạn console.log(a)

…finally

Đôi khi chúng ta cần chạy một đoạn code dù nó có bị lỗi hay không bị lỗi, nó cũng sẽ giống ở trên, nhưng viết nó sẽ rõ ràng hơn

const a = 4;

try {
  // b chưa được định nghĩa, nó sẽ báo lỗi
  console.log(b);
} catch (err) {
  console.error(err)
} finally {
  console.log(a);
}

Các hàm async

Hiện tại chúng ta có 3 cách để làm việc với các hàm async, cách xử lý lỗi nếu có trên 3 cách này: callback, Promise, async/await

callback

myAsyncFunc(someInput, (err, result) => {
    if(err) return console.error(err);
    console.log(result);
})

Promise

Promise.resolve(1)
  .then(res => {
    console.log(res) // 1
    throw new Error('something went wrong');
    return Promise.resolve(2);
  })
  .then(res => {
    // sẽ không chạy
    console.log(res);
  })
  .catch(err => {
    console.error(err);
    return Promise.resolve(3)
  })
  .then(res => {
    // (A)
    console.log(res) // 3
  })
  .catch(err => {
    // trong trường hợp block (A) xảy ra lỗi
    console.error(err)
  })

async/await

async function() {
  try {
    await someFuncThatThrowsAnError()
  } catch (err) {
    console.error(err) 
  }
  // vẫn chạy
  console.log('Easy!')
}

Hiển thị lỗi ở phía giao diện người dùng

Ví dụ chúng ta làm Single Page App bằng React, chúng ta muốn hiển thị lỗi trên giao diện như thế này

Có thể dùng React Portal để chèn vào hoặc dùng một component nhận vào Error Object và render ra trên giao diện

<div>
  <GobalError err={errorObj} reset={handleResetError} />
</div>

Nếu lỗi hiển thị dạng inline phía dưới input

<div>
  <input
      type="text"
  />
  <button onClick={this._callBackend}>Delete your city</button>
  <InlineError error={this.state.error} />
</div>

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

Tham khảo các vị trí tuyển dụng IT tại đà nẵng, hcm, hà nội tại đây

13 kênh Youtube lập trình tiếng Việt giúp bạn trở thành Fullstack developer

học lập trình fullstack

Học lập trình cho Fullstack Developer – Theo thống kê mỗi anh em lập trình viên trung bình dành 15-25 phút vi vu trên Youtube. Để không lãng phí 30 phút mỗi ngày thời gian fix bug và kiếm gấu, anh em nên save lại ngay list tổng hợp các kênh học lập trình ngon-bổ-hoàn toàn miễn phí dưới đây.

Tuyển lập trình viên Full Stack

Học lập trình cùng TOIDICODEDAO – PHẠM HUY HOÀNG

Chia sẻ kiến thức, kinh nghiệm về ngành lập trình, cuộc sống của lập trình viên. Có rất nhiều tutorial hay ho và gần gũi, thậm chí những người hoàn toàn không biết gì về code cũng có thể học lập trình.

CODEAHOLICGUY

Hoàng Nguyên – chủ blog codeaholicguy rầm rộ trong giới dev. Đây là kênh Vlog chia sẻ về kiến thức và cuộc sống lập trình viên truyền động lực cho những anh em muốn phát triển con đường coder.

KTEAM

Chanel hướng dẫn lập trình từ cơ bản đến nâng cao đa dạng ngôn ngữ lập trình C, C++, SQL server,… dành cho người không vững lập trình. Một kênh hoàn toàn miễn phí anh em newbie không thể bỏ qua.

ZENDVN – HỌC LẬP TRÌNH ONLINE

ZendVN thực chất là một kênh học lập trình trực tuyến, và channel Youtube này chia sẻ miễn phí các video tự học trên rất nhiều ngôn ngữ lập trình: NodeJS, Angular, VueJS, Python, PHP, HTML CSS, Javascript, ReatJS,…

KÊNH TOPDEV TV CHANNEL

Không chỉ chia sẻ về những kiến thức lập trình, TopDev TV Channel còn có nhiều nội dung liên quan đến các kỹ năng mềm dành cho lập trình viên ở đủ mọi trình độ. Một kênh youtube giúp các bạn có thể được học hỏi kinh nghiệm từ các chuyên gia hàng đầu tại Việt Nam.

TRUNG TÂM ĐÀO TẠO TIN HỌC KHOA PHẠM

Khó có một kênh Youtube miễn phí với chất lượng video được đầu tư như vậy. Anh em có thể tham khảo nguồn tự học về php, zend framework, laravel framework, lập trình android, … Ngoài ra kênh còn chia sẻ kiến thức sử dụng github cũng như một số bài tập để luyện tập sau khi kết thúc khoá học.

  TẤT TẦN TẬT VỀ PHP - Tìm hiểu về PHP như thế nào?

DẠY NHAU HỌC

Với câu slogan cực chất: “Học lập trình dạy cho ta cách suy nghĩ”, không chỉ là một channel gồm video tutorial kiến thức về C, C++ và cấu trúc dữ liệu mà đây còn là nơi chia sẻ những kĩ năng nghề nghiệp bổ ích cho các anh em lập trình.

KÊNH CỦA THIENTAMNGUYEN

Đây là kênh gồm video chia sẻ kiến thức: C, C++ chi tiết từ cơ bản đến nâng cao đòi hỏi người xem phải nghiền ngẫm và thực hành mới thành công được. Tôn chỉ của channel: “Có tư duy mới thành công.”

KÊNH CỦA VIỆT NAM SƠN NGUYỄN

Channel tập trung cung cấp kiến thức về C/C++ và C#. Bên cạnh đó các anh em có thể thử sức giải đề của các trường đại học.

KÊNH CỦA THẠCH PHẠM

Nếu bạn đang muốn học về HTML, CSS, WordPress từ cơ bản thì hãy tham khảo ngay channel của Thạch Phạm. Kênh gồm các video hướng dẫn từ khái niệm đến thực hành việc sử dụng WordPress, thủ thuật WordPress và đánh giá các plugin WordPress, review hosting.

NGHIEPUIT

Kênh giúp anh em học về các ngôn ngữ lập trình ReactJS, Java, NodeJS,.. với hướng dẫn từ kiến thức cơ bản đến nâng cao.

THƯ VIỆN LẬP TRÌNH

Ngoài những video giới thiệu về HTML, CSS,… anh em có thể học thiết kế bằng Photoshop tại kênh youtube này.

VIET IT VLOG

Kênh bao gồm các video hướng dẫn sử dụng máy tính internet, lập trình, sử dụng excel các phần mềm văn phòng.

Chúc anh em “tu luyện” thành công! Và đừng bỏ qua những bài viết hay dưới đây:

Xem thêm việc làm Front end DeveloperBack end Developer tại TopDev

TopDev tổng hợp

5 câu hỏi hoàn thiện kế hoạch quản lý nhân sự mùa Covid-19

5 câu hỏi hoàn thiện kế hoạch quản lý nhân sự mùa Covid-19

Những ngày gần đây, giới Nhân sự đang phải đối mặt với nhiều nguy cơ do diễn biến của dịch bệnh Covid-19 ngày càng phức tạp. Thách thức lớn nhất đối với các phòng nhân sự lúc này chính là phải có nhiệm vụ đưa ra các giải pháp khả thi nhằm cân bằng các mối lo ngại về an toàn lực lượng lao động với việc duy trì hoạt động doanh nghiệp như bình thường. Vì thế, họ cần phải hành động nhanh chóng để ứng phó mọi tình huống trước khi một cuộc khủng hoảng về nhân sự có thể diễn ra.

  Nhân sự nên làm gì giữa tâm bão Coronavirus

Bài viết sau đây sẽ giải đáp 5 câu hỏi để bạn có sự chuẩn bị tốt nhất về cách tiếp cận hiện trạng của vấn đề nhân sự đồng thời giúp thiết lập và điều chỉnh kế hoạch “tác chiến” trong đại dịch này.

1. Lựa chọn mô hình giải pháp Nhân sự: 50% hay 100%?

Covid-19 tạo ra rào cản lớn đối với các doanh nghiệp vì các triệu chứng mà chúng gây ra. Phải mất từ 2 đến 14 ngày sau khi tiếp xúc với người nhiễm bệnh, các triệu chứng mới quá phát, mở ra cơ hội lây lan trên diện rộng của doanh nghiệp. Mặt khác, thời gian phục hồi trung bình của những người bị nhiễm chủng virus mới này là khoảng 2 tuần hoặc có thể lâu hơn tùy vào thể trạng. 

5 câu hỏi hoàn thiện kế hoạch quản lý nhân sự mùa Covid-19

Thực tế đó cho thấy, các doanh nghiệp cần lựa chọn và áp dụng mô hình giải pháp nhân sự phù hợp nhất. Thực hiện giải pháp 50% số lượng nhân viên làm việc tại công ty trong một thời gian. Hãy bắt đầu xác định các chức năng nhân sự quan trọng, những công việc có tính trọng tâm để giảm thiểu sự gián đoạn trong quy trình phát triển chung. 

Khi nhận thấy tình hình dịch bệnh chưa vẫn chưa được kiểm soát và ngày càng gia tăng thì việc các doanh nghiệp nên làm đó là ưu tiên về tính an toàn cho người lao động. Hãy áp dụng giải pháp “Work from home” – cho phép các nhân viên triển khai và theo dõi các hoạt động nhân sự tại nhà hoặc làm việc từ xa. Đây là cách thức hữu hiệu nhất không chỉ trong công tác phòng- chống dịch bệnh mà còn đảm bảo được tiến độ công việc.

2. Làm thế nào để cân đối: Sức khỏe và hạnh phúc của nhân viên?

Đây được xem là một vấn đề “lớn”. Việc chưa nắm bắt những thông một cách chính xác có thể khiến các nhân viên lo lắng và hoảng loạn, làm ảnh hưởng đến sức khỏe tinh thần và hiệu suất công việc.

5 câu hỏi hoàn thiện kế hoạch quản lý nhân sự mùa Covid-19

Vì thế, việc đưa ra chính sách làm việc từ xa phù hợp với người lao động là điều cần thiết. Hãy đặt vấn đề sức khỏe và hạnh phúc của nhân viên lên hàng đầu bằng cách cung cấp thông tin về các bước cần thực hiện:

  • Nắm bắt những thông tin cơ bản về Covid-19.
  • Đặt khăn và chất khử trùng tay có chứa ít nhất 60% cồn xung quanh nơi làm việc kết hợp rửa tay đúng cách..
  • Thông báo cho nhân viên về những biện pháp phòng ngừa dịch bệnh một cách cụ thể.
  • Cập nhật các chính sách PTO (chính sách nghỉ phép nhưng vẫn được hưởng lương): Chính sách này giúp hỗ trợ người lao động bị bệnh và kiểm soát, thúc đẩy sự phân bổ công tác quản trị các đầu công việc sao cho hiệu quả.

3. Nếu bệnh tật dẫn đến làm việc từ xa, nhân viên có được đào tạo chéo và đảm nhiệm nhiều công việc không?

Đây cũng là một trong những vấn đề khiến doanh nghiệp đau đầu. Tuy nhiên, việc đào tạo chéo vẫn có thể diễn ra với điều kiện cá nhân thay thế có những hiểu biết cơ bản về công việc của vị trí đã vắng mặt. 

5 câu hỏi hoàn thiện kế hoạch quản lý nhân sự mùa Covid-19

Chẳng hạn như, front-end developer có thể hỗ trợ các nhu cầu back-end để duy trì trang web của bạn không vì họ sở hữu chung một background (kiến thức nền) Điều quan trọng là cần xác định được các chức năng chuyên môn nhân sự quan trọng trước khi cân nhắc việc có đào tạo chéo để hỗ trợ họ trong công việc hay không.

Một giải pháp khác có thể khắc phục tình trạng này đó là nhờ vào lực lượng lao động dự phòng (tức nguồn lực đang được quản lý và theo dõi bởi bộ phận nhân sự sau quá trình tuyển dụng). Họ là nguồn lực phù hợp nhất vào thời điểm này vì có thể nắm bắt, học hỏi và nâng cao kỹ năng nhanh chóng.

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

4. Những phần mềm/công cụ kỹ thuật nào cần thiết cần thiết cho lực lượng lao động tại nhà?

Theo một cuộc khảo sát từ Gartner, 54% các nhà lãnh đạo nhân sự chia sẻ rằng công nghệ và cơ sở hạ tầng kỹ thuật kém là rào cản lớn nhất trong việc tạo ra tính hiệu quả khi thực hiện công việc từ xa. Tùy thuộc vào từng tính chất công việc, lực lượng lao động tại nhà của các doanh nghiệp có nhiều sự lựa chọn trong việc sử dụng các phần mềm hỗ trợ.

5 câu hỏi hoàn thiện kế hoạch quản lý nhân sự mùa Covid-19

Ngoài các thiết bị thiết yếu cần có như: điện thoại, máy tính, tai nghe thì TopDev gợi ý một số phần mềm/công cụ kỹ thuật nổi trội như sau: 

5. Thủ tục “cấp tốc” trong công tác nhân sự

Sự mơ hồ là kẻ thù trong bất kỳ tình huống khẩn cấp nào, đó là lý do tại sao bạn nên tập hợp một danh sách các hướng dẫn từng bước cụ phòng ngừa việc nhân viên của bạn không may mắc phải Covid-19 hoặc có tiếp xúc với nguồn dịch bệnh. 

Các hướng dẫn bao gồm:

  • Liên hệ với người quản lý nhân sự để thông báo về kế hoạch di trú của bạn trọng thời gian gần đây.
  • Ghi nhận những tư vấn, lời khuyên của nhà cung cấp bảo hiểm y tế của công ty bạn.
  • Tự kiểm dịch hoặc có kế hoạch phòng dịch tại nhà theo quy trình chung của chính phủ để theo dõi tình trạng sức khỏe của bản thân.

Như đã đề cập, không có một khẳng định khi nào đại dịch coronavirus sẽ kết thúc. Các doanh nghiệp cần được thông báo khi tình hình phát triển và sẵn sàng.

Hãy nhớ rằng một kế hoạch phòng chống đại dịch hiệu quả nên ưu tiên an toàn cho các nhân viên và giảm thiểu sự gián đoạn của quy trình phát triển của tổ chức/doanh nghiệp. Tất cả chúng ta – những nhà quản trị nhân sự và các nhân viên phải luôn sẵn sàng giải quyết những khó khăn mà ngành Nhân sự sắp phải đối mặt.

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

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

Áp dụng Rate Limiting vào hệ thống như thế nào?

rate limiting

Trong bài trước chúng ta đã cùng tìm hiểu các thuật toán của kĩ thuật Rate Limiting – chống DDOS và hạn chế việc bị spam khiến sập hệ thống. Còn lần này, ta sẽ phân tích kỹ hơn cách cách các hệ thống lớn sử dụng Rate Limiting. Từ đó có bài học để bảo vệ hệ thống của chúng ta nhé!

Facebook, Google, LinkedIn đã ứng dụng Rate Limiting vào API như thế nào?

Để có thể hiểu được những điều mình sắp kể ra thì các bạn chưa biết về Rate Limiting thì đọc lại phần 1 nha (Để dễ theo dõi hơn ý mà <3):

  • Leaky Bucket
  • Token Bucket
  • Fixed Window
  • Sliding Window

Với những công ty có hệ thống website lớn như Google, Facebook đều cung cấp API cho các bên thứ 3 sử dụng. Tuy nhiên, họ đều giới hạn lại để chống kẻ xấu spam và dùng quá nhiều tài nguyên của hệ thống.

rate limiting

Youtube API: Mỗi application chỉ được cấp 10000 unit/ngày. Mỗi lần gọi API sẽ tốn 1 unit nhất định, API tìm kiếm thì tầm 50 unit, API upload thì tầm 1000 unit. Cách này chắc là dựa theo thuật toán Token Bucket.

Github API: Cho phép mỗi người dùng gọi 5000 request/giờ. Nếu chưa đăng nhập thì chỉ được 60 request/giờ. Như vậy ta có thể thấy họ áp dụng Sliding Window hoặc Fixed Window.

rate limiting

Facebook API: Facebook thì rất thoải mái trong việc cấp API: Lấy thông tin cá nhân, quản lý page, chạy quảng cáo… Phần lớn API dùng Platform Rate Limit, các API liên quan tới Marketing và Instagram sẽ có khoảng giới hạn riêng.

Rate Limit của Facebook không có một con số cố định như các bên ở trên mà nó khá thú vị, chúng phụ thuộc vào số lượng user trong app của bạn. App càng nhiều user thì có thể gọi API càng nhiều lần, nghe có lý phết!

rate limiting

Nhưng dân mình khá là ĐỈNH CAO nên nhiều khi họ tìm được các API ẩn, hoặc chạy tự động để làm nhiều trò mà API không cho phép.

Do đó, những website lớn như Facebook, Google đôi khi họ còn phải áp dụng cả AI/ML, dựa theo hành vi người dùng để xác định xem là người hay là MÁY.

Đặt Rate Limit vào hệ thống

Về cơ bản, áp dụng Rate Limiting vào hệ thống là một chuyện … cũng không quá phức tạp, nhất là với các hệ thống nhỏ.

Đa phần các web framework (Spring, ExpressJS, Ruby on Rails, …) đều có thư viện hỗ trợ. Chỉ cần add vào, chỉnh vài dòng code là xong.

Theo mình thấy, thường người ta sẽ setup Rate Limiting ở tầm Load Balancer hoặc Web Server. Lý do là vì web app của bạn chỉ nên tập trung vào business logic, những thứ như SSL Termination, Rate Limiting để Web Server quản lý sẽ tốt hơn, dễ thay đổi mà không cần sửa code.

rate limiting

Tuy nhiên, khó khăn nằm ở chỗ tinh chỉnh các tham số sao cho phù hợp. Chặn lỏng lẻo quá thì vô tác dụng, chặn quá tay thì user sẽ thấy bị chậm, khó chịu, không gọi được API.

Sau đây là 1 số kinh nghiệm của mình khi dùng Rate Limit:

  • Public API là những API có thể gọi mà không cần token: Đăng nhập, Gửi tin nhắn, quên mật khẩu, search… API càng public hoặc càng quan trọng thì rate limit càng thấp.  Lý do là những API này rất dễ bị lợi dụng để spam, làm quá tải hệ thống.
  • Cân bằng giữa việc tăng Rate Limit và trải nghiệm người dùng. Nên cho phép tăng limit nếu người dùng đã đăng nhập, có nhiều quyền, trả phí v…v
  • Khi người dùng gọi API quá limit thì làm gì?
    • Throttle: nginx có khái niệm burst khá hay, những request vượt limit sẽ được đưa vào 1 queue, xử lý từ từ. Người dùng chỉ thấy bị chậm nhưng không bị lỗi. Kĩ thuật này gọi là throttle
    • Return Error: Server trả về HTTP Code 429 – Too Many Requests để phía client biết mà xử lý
    • Shadow Ban: Có thể bạn sẽ gặp bọn chơi xấu, gọi API liên tục đến khi gặp lỗi 429 thì chúng tạo account mới để gọi. Lúc này ta có thể dùng Shadow Ban, vẫn trả về HTTP 200 nhưng … không làm gì hết, để đánh lừa bọn đó :))
rate limiting

Điều quan trọng nhất là bạn phải dựa vào business và requirement của hệ thống để ra quyết định nhé! Ví dụ web ngân hàng thì đăng nhập sai 3 lần là khoá và cảnh báo liền; còn web xem phim giáo dục giới tính thì đăng nhập nhầm 5-10 lần cũng chẳng chết ai đâu.

Túm lại

Như các bạn thấy,  Rate Limiting là một kĩ thuật/thuật toán đơn giản, hay ho nhưng lại ít khi nào được nhắc đến trong chương trình học hay các tài liệu trên mạng. Nhưng chúng lại rất hữu dụng, bảo vệ chúng ta khỏi bị DDOS, chống spam, đảm bảo người dùng có thể tận hưởng việc gọi API một cách trơn tru. Nếu bạn thấy bài này có ích thì share nha, còn nếu có gì mình sai sót thì anh em comment ở dưới để mình tìm hiểu lại nhé. Cảm ơn các bạn đã đọc.

Ngoài ra còn nhiều bài khác liên quan đến tối ưu hóa website:

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

Nên dùng gì thay cho input number

nen-dung-gi-thay-cho-input-number
Ngoài input type number, còn những giá trị gì bạn nên cân nhắc sử dụng

Có thể bạn sẽ nghĩ ngay đến <input type='number' /> khi muốn cho user nhập số. Tuy nhiên đời không như là mơ, nó có kha khá vấn đề, đôi khi có những giá trị nhìn thì như số, nhưng không phải (như credit card), hoặc một dạng chuỗi số.

Trên Gov.uk họ dùng kiểu này

<input type="text" inputmode="numeric" pattern="[0-9]*">

Thuộc tính inputmode cũng khá hay ho, được đề cập rất cụ thể ở đây

Tóm tắt lại cho bạn nào lười đọc

tel

<input type="text" inputmode="tel" />

decimal

<input type="text" inputmode="decimal" />

Email

<input type="text" inputmode="email" />

Url

<input type="text" inputmode="url" />

<input type="text" inputmode="search" />

Hoặc để nhập vào mã code xác thực, Twilio sử dụng định dạng này

<input
  type="text"
  name="token"
  id="token"
  inputmode="numeric"
  pattern="[0-9]*"
  autocomplete="one-time-code"
/>

Với autocomplete="one-time-code" chúng ta sẽ có được tính năng tự điền như thế này

iOS screen with a numeric input and a text message offering to auto-fill the two-factor auth

Xem danh sách autocomplete đầy đủ

What to Use Instead of Number Inputs

Bài viết gốc tại Vuilaptrinh

Tìm hiểu Currying function trong Javascript

Bài viết này chúng ta sẽ tìm hiểu về cái cà-ri – currying function này, nó chạy ra sao, hữu dụng thế nào.

Bạn sẽ gặp kiểu lập trình truyền vào function như một argument (callback) cho một function khác không chỉ trong Javascript mà còn có thể thấy ở Haskell, Clojure, Erlang và Scala

Việc sử dụng function như một argument đẻ ra thêm một số khái niệm khác: Pure function*, **CurryingHigher-Order Function

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

Thế nào gọi là Carrying?

Thay vì truyền vào cho function 1 lúc nhiều argument, chúng ta lại chuyển kiểu viết đó thành 1 function chỉ nhận 1 argument, nhưng bên trong đó chúng ta lòng các function con bên trong, và return về function con này.

Ví dụ cho dễ hiểu hé. Đây là kiểu viết truyền nhiều argument ai cũng biết.

function multiply(a, b, c) {
    return a * b * c;
}
multiply(1,2,3); // 6

Đây là phiên bản cà-ry của function multiply ở trên, kết quả cuối cùng cũng ko thay đổi.

function multiply(a) {
    return (b) => {
        return (c) => {
            return a * b * c
        }
    }
}

log(multiply(1)(2)(3)) // 6

Bạn có thể chửi viết chi mà phức con mẹ nó tạp vậy, callback hell. Nhưng lợi ích của nó là giúp chúng ta gọi được hàm multiply theo kiểu multiply(1)(2)(3) thay vì `multiply(1,2,3). Vẫn chưa thấy lợi ích? Hy vọng viết thế này bạn sẽ thấy được công năng của nó

const mul1 = multiply(1);
const mul2 = mul1(2);
const result = mul2(3);
// result : 6

Tận dụng scope mà mul2 có thể truy xuất đến kết quả của mul1. Dù đã được gọi nhưng kết quả của multiply sẽ ko chết liền mà vẫn tồn tại cho đến khi chạy đến lần gọi sau cùng.

Bạn cũng có thể viết Currying function theo kiểu sau

function volume(a) {
    return (b, c) => {
        return a * b * c
    }
}
volume(70)(90,30);
volume(70)(390,320);
volume(70)(940,340);

Currying có hữu dụng không?

Thí dụ bạn có một hàm để tính giá trị discount, giảm ngay 10% cho khách hàng thân thiết.

function discount(price, discount) {
    return price * discount
}
// Giảm ngay 50 đồng khi khách hàng đã tiêu 500 đồng.
const price = discount(500,0.10); // $50 
// $500  - $50 = $450

Khách hàng tiêu tiền điên cuồng, chúng ta gọi hàm này say mê

const price = discount(1500,0.10); // $150
// $1,500 - $150 = $1,350
const price = discount(2000,0.10); // $200
// $2,000 - $200 = $1,800
const price = discount(50,0.10); // $5
// $50 - $5 = $45
const price = discount(5000,0.10); // $500
// $5,000 - $500 = $4,500
const price = discount(300,0.10); // $30
// $300 - $30 = $270

Chúng ta có thể đưa vào giá trị discount ở lần đầu tiên, đến các lần gọi tiếp theo, chúng ta ko cần truyền giá trị 10% này nữa

function discount(discount) {
    return (price) => {
        return price * discount;
    }
}
const tenPercentDiscount = discount(0.1);
tenPercentDiscount(500); // $50
const twentyPercentDiscount = discount(0.2);
twentyPercentDiscount(500); // 100
// $500 - $100 = $400
twentyPercentDiscount(5000); // 1000
// $5,000 - $1,000 = $4,000
twentyPercentDiscount(1000000); // 200000
// $1,000,000 - $200,000 = $600,000

Nói một cách ngắn gọn, khi cần truyền vào 1 argument ít thay đổi, cố định trong đa số các trường hợp, nghĩ đến carrying.

Chuyển bất cứ hàm nào thành hàm Currying

Chúng ta sẽ viết một cái hàm, nhiệm vụ của nó là biến một hàm bất kỳ và trả về một phiên bản currying của function đó.

function curry(fn, ...args) {
    return (..._arg) => {
        return fn(...args, ..._arg);
    }
}

Giải thích hàm này nha, hàm curry này nhận vào argument đầu tiên là một function, các argument tiếp theo sẽ là giá trị số. Sử dụng với hàm multiply ban đầu

function multiply(a, b, c) {
    return a * b * c;
}
// phiên bản currying
const multiplyCurrying = curry(multiply,2);
multiplyCurrying(4);
multiplyCurrying(6);

Understanding currying in javascript

TopDev via Vuilaptrinh

Tuyển dụng lập trình viên trên TopDev

Làm sao để fetch dữ liệu bằng React Hook

lam-sao-de-fetch-du-lieu-bang-react-hook

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

Trong bài này chúng ta sẽ sử dụng React.useState, React.useEffect, React.useReducer để fetch dữ liệu từ API, đồng thời cũng viết một custom hook để có thể sử dụng ở bất kỳ đâu

Chúng ta có một component, dữ liệu của component này sẽ được lấy từ API

import React, { useState } from 'react';

function App() {
  const [data, setData] = useState({ hits: [] });
  return (
    <ul>
      {data.hits.map(item => (
        <li key={item.objectID}>
          <a href={item.url}>{item.title}</a>
        </li>
      ))}
    </ul>
  );
}
export default App;

Chúng ta sẽ sử dụng axios để fetch dữ liệu, bạn thích xài cái khác thì cứ vô tư

import React, { useState, useEffect } from 'react';
import axios from 'axios';

function App() {
  const [data, setData] = useState({ hits: [] });
  
  useEffect(async () => {
    const result = await axios(
      'https://hn.algolia.com/api/v1/search?query=redux',
    );
    setData(result.data);
  });

  return (
    <ul>
      {data.hits.map(item => (
        <li key={item.objectID}>
          <a href={item.url}>{item.title}</a>
        </li>
      ))}
    </ul>
  );
}
export default App;

Bên trong React.useEffect chúng ta sẽ thực hiện việc fetch data từ API, sau khi nhận được dữ liệu gán giá trị nhận được cho giá trị của state data

Nếu dừng ở đây, khi chạy bạn sẽ thấy một vòng lặp vô tận của việc gọi fetch data. Effect sẽ chạy không chỉ ở lúc component mount mà còn ở các lần update tiếp theo. Bởi vì chúng ta gán giá trị state trên mỗi lần fetch, component lại được update và effect lại được gọi lại để chạy. Chúng ta chỉ muốn fetch data khi component mount lần đầu tiên. Đó là lý do chúng ta phải thêm một mảng rỗng vào tham số thứ hai của effect, như vậy các lần update tiếp theo nó sẽ không được gọi.

import React, { useState, useEffect } from 'react';
import axios from 'axios';

function App() {
  const [data, setData] = useState({ hits: [] });
  
  useEffect(async () => {
    const result = await axios(
      'https://hn.algolia.com/api/v1/search?query=redux',
    );
    setData(result.data);
  }, []);
  
  return (
    <ul>
      {data.hits.map(item => (
        <li key={item.objectID}>
          <a href={item.url}>{item.title}</a>
        </li>
      ))}
    </ul>
  );
}
export default App;

 

Tham số thứ 2 truyền vào cho effect này là danh sách những giá trị nào mà hook phụ thuộc, tức nếu các giá trị này thay đổi thì effect được gọi lại. Bỏ array trống sẽ không còn chuyện chạy ở lần update.

Trong đoạn code trên vẫn còn một chỗ phải chỉnh sửa, chúng ta sử dụng async/awaittheo như định nghĩa, tất cả những hàm nào là async sẽ được ngầm hiểu là trả về một Promise. Tuy nhiên, cũng theo như định nghĩa effect hook không được trả về gì cả, hoặc một function để clean up (xem lại bài nói về Hook Effect, có giải thích 2 loại Effect Hook).

Nên bạn mà copy đoạn trên mà chạy thì sẽ nhận thông báo bên dưới console. Không thể sử dụng async function bên trong React.useEffect, chúng ta sửa lại

useEffect(() => {
  const fetchData = async () => {
    const result = await axios(
      'https://hn.algolia.com/api/v1/search?query=redux',
    );
    setData(result.data);
  };
  fetchData();
}, []);

Để fetch dữ liệu bằng React.useEffect có thể tóm gọn như ở trên. Chúng ta sẽ tiếp tục xem cách handle error, loading indicator, gọi fetch từ form và làm thế nào tái sử dụng hook để fetch

Gọi hook thủ công/bằng code

Chúng ta đã xong phần fetch dữ liệu một lần lúc component mount. Nhưng làm thế nào để fetch dữ liệu khi có sự kiện từ user, ví dụ ô search, khi user nhập lấy danh sách kết quả tìm kiếm. Ví dụ bên dưới mặc định sẽ hiển thị kết quả cho từ khóa redux, nếu user nhập vào một giá trị khác, chúng ta cần làm sao để chạy useEffect một lần nữa

import React, { Fragment, useState, useEffect } from 'react';
import axios from 'axios';

function App() {
  const [data, setData] = useState({ hits: [] });
  const [query, setQuery] = useState('redux');
  
  useEffect(() => {
    const fetchData = async () => {
      const result = await axios(
        'https://hn.algolia.com/api/v1/search?query=redux',
      );
      setData(result.data);
    };
    fetchData();
  }, []);
  
  return (
    <Fragment>
      <input
        type="text"
        value={query}
        onChange={event => setQuery(event.target.value)}
      />
      <ul>
        {data.hits.map(item => (
          <li key={item.objectID}>
            <a href={item.url}>{item.title}</a>
          </li>
        ))}
      </ul>
    </Fragment>
  );
}
export default App;

Với nhu cầu như trên, chúng ta cần cập nhập lại useEffect

useEffect(() => {
  const fetchData = async () => {
    const result = await axios(
      `http://hn.algolia.com/api/v1/search?query=${query}`,
    );
    setData(result.data);
  };
  fetchData();
}, []);

Tuy nhiên, nếu chỉ như vậy, hàm fetchData sẽ không được gọi khi user input một giá trị mới vào ô tìm kiếm. Vì chúng ta đã truyền vào một mảng rỗng vào cho giá trị depend của effect, nên nó chỉ chạy lần đầu mount

useEffect(() => {
  const fetchData = async () => {
    const result = await axios(
      `http://hn.algolia.com/api/v1/search?query=${query}`,
    );
    setData(result.data);
  };
  fetchData();
}, [query]);

Có một vấn đề khác, user cứ nhập một ký tự, câu fetchData lại được gọi, gọi liên tục như vậy không hay, thêm vào một nút để user click vào mới thực hiện search thì sao

function App() {
  const [data, setData] = useState({ hits: [] });
  const [query, setQuery] = useState('redux');
  const [search, setSearch] = useState('');
  
  useEffect(() => {
    const fetchData = async () => {
      const result = await axios(
        `http://hn.algolia.com/api/v1/search?query=${query}`,
      );
      setData(result.data);
    };
    fetchData();
  }, [query]);
  
  return (
    <Fragment>
      <input
        type="text"
        value={query}
        onChange={event => setQuery(event.target.value)}
      />
      <button type="button" onClick={() => setSearch(query)}>
        Search
      </button>
      <ul>
        {data.hits.map(item => (
          <li key={item.objectID}>
            <a href={item.url}>{item.title}</a>
          </li>
        ))}
      </ul>
    </Fragment>
  );
}

Giờ effect phải phụ thuộc vào search, không chạy khi user nhập vào input

function App() {
  const [data, setData] = useState({ hits: [] });
  const [query, setQuery] = useState('redux');
  const [search, setSearch] = useState('redux');
  
  useEffect(() => {
    const fetchData = async () => {
      const result = await axios(
        `http://hn.algolia.com/api/v1/search?query=${search}`,
      );
      setData(result.data);
    };
    fetchData();
  }, [search]);
  
  return (
    ...
  );
}

Nhưng nếu sửa như vậy, trường hợp component được mount lần đầu, nó sẽ không có hiển thị kết quả cho từ khóa redux nữa. Nếu dùng thềm một useEffect khác cho trường hợp chạy lúc đầu sẽ gây nhầm lẫn, không rõ ràng, thay vào đó nếu chúng ta xem search state là nguyên cái url sẽ đơn giản hơn

function App() {
  const [data, setData] = useState({ hits: [] });
  const [query, setQuery] = useState('redux');
  const [url, setUrl] = useState(
    'https://hn.algolia.com/api/v1/search?query=redux',
  );
  
  useEffect(() => {
    const fetchData = async () => {
      const result = await axios(url);
      
      setData(result.data);
    };
    
    fetchData();
  }, [url]);
  
  return (
    <Fragment>
      <input
        type="text"
        value={query}
        onChange={event => setQuery(event.target.value)}
      />
      <button
        type="button"
        onClick={() =>
          setUrl(`http://hn.algolia.com/api/v1/search?query=${query}`)
        }
      >
        Search
      </button>
      <ul>
        {data.hits.map(item => (
          <li key={item.objectID}>
            <a href={item.url}>{item.title}</a>
          </li>
        ))}
      </ul>
    </Fragment>
  );
}

Loading indicator

Một nhu cầu khác cũng hay gặp là trong lúc fetch data từ API, chúng ta cần biết trạng thái loading tới đâu rồi, chúng ta sẽ bổ sung thêm state isLoading

function App() {
  const [data, setData] = useState({ hits: [] });
  const [query, setQuery] = useState('redux');
  const [url, setUrl] = useState(
    'https://hn.algolia.com/api/v1/search?query=redux',
  );
  const [isLoading, setIsLoading] = useState(false);
  
  useEffect(() => {
    const fetchData = async () => {
      setIsLoading(true);
      
      const result = await axios(url);
      
      setData(result.data);
      setIsLoading(false);
    };
    fetchData();
  }, [url]);
  
  return (
    <Fragment>
      <input
        type="text"
        value={query}
        onChange={event => setQuery(event.target.value)}
      />
      <button
        type="button"
        onClick={() =>
          setUrl(`http://hn.algolia.com/api/v1/search?query=${query}`)
        }
      >
        Search
      </button>
      {isLoading ? (
        <div>Loading ...</div>
      ) : (
        <ul>
          {data.hits.map(item => (
            <li key={item.objectID}>
              <a href={item.url}>{item.title}</a>
            </li>
          ))}
        </ul>
      )}
    </Fragment>
  );
}
export default App;

Handle Error

Cũng tương tự như loading, chúng ta sẽ bổ sung thêm state isError để xác định việc fetch dữ liệu có bị lỗi không

function App() {
  const [data, setData] = useState({ hits: [] });
  const [query, setQuery] = useState('redux');
  const [url, setUrl] = useState(
    'https://hn.algolia.com/api/v1/search?query=redux',
  );
  const [isLoading, setIsLoading] = useState(false);
  const [isError, setIsError] = useState(false);
  
  useEffect(() => {
    const fetchData = async () => {
      setIsError(false);
      setIsLoading(true);
      
      try {
        const result = await axios(url);
        
        setData(result.data);
      } catch (error) {
        setIsError(true);
      }
      
      setIsLoading(false);
    };
    fetchData();
  }, [url]);
  return (
    <Fragment>
      <input
        type="text"
        value={query}
        onChange={event => setQuery(event.target.value)}
      />
      <button
        type="button"
        onClick={() =>
          setUrl(`http://hn.algolia.com/api/v1/search?query=${query}`)
        }
      >
        Search
      </button>
      {isError && <div>Something went wrong ...</div>}
      {isLoading ? (
        <div>Loading ...</div>
      ) : (
        <ul>
          {data.hits.map(item => (
            <li key={item.objectID}>
              <a href={item.url}>{item.title}</a>
            </li>
          ))}
        </ul>
      )}
    </Fragment>
  );
}

Fetch data với Form

Nãy giờ chúng ta chỉ fetch data với bằng input và button. Khi có nhiều element hơn, chúng ta sẽ đưa nó vào form để có thể trigger form submit bằng cách nhấn Enter

function App() {
  ...
  return (
    <Fragment>
      <form
        onSubmit={event =>
          setUrl(`http://hn.algolia.com/api/v1/search?query=${query}`)
          event.preventDefault();
        }
      >
        <input
          type="text"
          value={query}
          onChange={event => setQuery(event.target.value)}
        />
        <button type="submit">Search</button>
      </form>
      {isError && <div>Something went wrong ...</div>}
      ...
    </Fragment>
  );
}

Tìm việc làm React lương cao cho SV mới ra trường tại đây

Custom hook để Fetch data

Để tái sử dụng được các đoạn code liên quan đến việc fetch data, chúng ta sẽ đưa nó ra thành một custom hook, các giá trị liên quan trực tiếp đến việc fetch data, cụ thể là loading, error chúng ta cũng đưa vào trong custom hook

const useHackerNewsApi = () => {
  const [data, setData] = useState({ hits: [] });
  const [url, setUrl] = useState(
    'https://hn.algolia.com/api/v1/search?query=redux',
  );
  const [isLoading, setIsLoading] = useState(false);
  const [isError, setIsError] = useState(false);
  
  useEffect(() => {
    const fetchData = async () => {
      setIsError(false);
      setIsLoading(true);
      try {
        const result = await axios(url);
        setData(result.data);
      } catch (error) {
        setIsError(true);
      }
      setIsLoading(false);
    };
    
    fetchData();
  }, [url]);
  
  return [{ data, isLoading, isError }, setUrl];
}

Sử dụng bên trong App Component

function App() {
  const [query, setQuery] = useState('redux');
  const [{ data, isLoading, isError }, doFetch] = useHackerNewsApi();
  
  return (
    <Fragment>
      <form onSubmit={event => {
        doFetch(`http://hn.algolia.com/api/v1/search?query=${query}`);
        event.preventDefault();
      }}>
        <input
          type="text"
          value={query}
          onChange={event => setQuery(event.target.value)}
        />
        <button type="submit">Search</button>
      </form>
      ...
    </Fragment>
  );
}

Giá trị state lúc khởi tạo của thể đưa vào như một tham số truyền vào cho custom hook luôn

import React, { Fragment, useState, useEffect } from 'react';
import axios from 'axios';

const useDataApi = (initialUrl, initialData) => {
  const [data, setData] = useState(initialData);
  const [url, setUrl] = useState(initialUrl);
  const [isLoading, setIsLoading] = useState(false);
  const [isError, setIsError] = useState(false);
  
  useEffect(() => {
    const fetchData = async () => {
      setIsError(false);
      setIsLoading(true);
      try {
        const result = await axios(url);
        setData(result.data);
      } catch (error) {
        setIsError(true);
      }
      setIsLoading(false);
    };
    
    fetchData();
  }, [url]);
  
  return [{ data, isLoading, isError }, setUrl];
};

function App() {
  const [query, setQuery] = useState('redux');
  const [{ data, isLoading, isError }, doFetch] = useDataApi(
    'https://hn.algolia.com/api/v1/search?query=redux',
    { hits: [] },
  );
  
  return (
    <Fragment>
      <form
        onSubmit={event => {
          doFetch(
            `http://hn.algolia.com/api/v1/search?query=${query}`,
          );
          event.preventDefault();
        }}
      >
        <input
          type="text"
          value={query}
          onChange={event => setQuery(event.target.value)}
        />
        <button type="submit">Search</button>
      </form>
      {isError && <div>Something went wrong ...</div>}
      {isLoading ? (
        <div>Loading ...</div>
      ) : (
        <ul>
          {data.hits.map(item => (
            <li key={item.objectID}>
              <a href={item.url}>{item.title}</a>
            </li>
          ))}
        </ul>
      )}
    </Fragment>
  );
}
export default App;

Reducer hook

Với cái custom hook để fetch data như ở trên, chúng ta thấy có 2 state isLoadingisError quan hệ khá mật thiết với nhau, có thể hợp nhất 2 đứa nó lại bằng React.useReducer

import React, {
  Fragment,
  useState,
  useEffect,
  useReducer,
} from 'react';
import axios from 'axios';

const dataFetchReducer = (state, action) => {
  ...
};

const useDataApi = (initialUrl, initialData) => {
  const [url, setUrl] = useState(initialUrl);
  
  const [state, dispatch] = useReducer(dataFetchReducer, {
    isLoading: false,
    isError: false,
    data: initialData,
  });
  ...
};

React.useReducer sẽ nhận vào một hàm reducer (công dụng tương tự như hàm reducer của redux ấy) và các giá trị khởi tạo của state, trong trường hợp của chúng ta là isLoading và isError. Việc này chẳng qua là gom tất cả state liên quan vào một object cho nó tinh tế thôi, thay vì từng state riêng biệt như sử dụng useState

const dataFetchReducer = (state, action) => {
  ...
};

const useDataApi = (initialUrl, initialData) => {
  const [url, setUrl] = useState(initialUrl);
  
  const [state, dispatch] = useReducer(dataFetchReducer, {
    isLoading: false,
    isError: false,
    data: initialData,
  });
  
  useEffect(() => {
    const fetchData = async () => {
      dispatch({ type: 'FETCH_INIT' });
      try {
        const result = await axios(url);
        dispatch({ type: 'FETCH_SUCCESS', payload: result.data });
      } catch (error) {
        dispatch({ type: 'FETCH_FAILURE' });
      }
    };
    fetchData();
  }, [url]);
  
  ...
};

 

Mình đã bảo rồi, nó sẽ giống như cái reducer trong redux thôi, chúng ta dispatch một object gồm type và payload, căn cứ vào payload mà chúng ta xử lý, cập nhập state

Cuối cùng chúng ta cập nhập lại giá trị trả về của custom hook nữa

const useDataApi = (initialUrl, initialData) => {
  const [url, setUrl] = useState(initialUrl);
  
  const [state, dispatch] = useReducer(dataFetchReducer, {
    isLoading: false,
    isError: false,
    data: initialData,
  });
  
  ...
  
  return [state, setUrl];
};

Cuối cùng, không kém phần quan trọng, phần code thực hiện bên trong dataFetchReducer

const dataFetchReducer = (state, action) => {
  switch (action.type) {
    case 'FETCH_INIT':
      return {
        ...state,
        isLoading: true,
        isError: false
      };
    case 'FETCH_SUCCESS':
      return {
        ...state,
        isLoading: false,
        isError: false,
        data: action.payload,
      };
    case 'FETCH_FAILURE':
      return {
        ...state,
        isLoading: false,
        isError: true,
      };
    default:
      throw new Error();
  }
};

Bỏ qua việc fetch data

Tình huống là khi user chuyển qua một route khác, khi đang fetch data, việc gọi fetch ko cần thiết và có thể bỏ qua

const useDataApi = (initialUrl, initialData) => {
  const [url, setUrl] = useState(initialUrl);
  
  const [state, dispatch] = useReducer(dataFetchReducer, {
    isLoading: false,
    isError: false,
    data: initialData,
  });
  
  useEffect(() => {
    let didCancel = false;
    
    const fetchData = async () => {
      dispatch({ type: 'FETCH_INIT' });
      try {
        const result = await axios(url);
        if (!didCancel) {
          dispatch({ type: 'FETCH_SUCCESS', payload: result.data });
        }
      } catch (error) {
        if (!didCancel) {
          dispatch({ type: 'FETCH_FAILURE' });
        }
      }
    };
    
    fetchData();
    
    return () => {
      didCancel = true;
    };
    
  }, [url]);
  
  return [state, setUrl];
};

Với việc return một function ở cuối của React.useEffect, tên gọi các bạn React đặt là clean up function, nằm trong kiểu effect cần clean up – nói thật mình phát mệt với việc các bạn trong team React cứ thích chế thêm liên tục như vậy.

Tham khảo thêm các vị trí tuyển dụng React hấp dẫn tại Topdev

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

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

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

Không đơn thuần chỉ là một cái vỗ nhẹ từ phía sau, hầu hết các nhân viên đều mong muốn nhận được sự quan tâm nhiều hơn của sếp để duy trì động lực làm việc. Đó là lý do tại sao nhiều nhà tuyển dụng lựa chọn việc thực hiện các chương trình khuyến khích để tạo sự gắn kết, thúc đẩy nhân viên làm việc chăm chỉ hơn. 

Thế nào là tạo động lực cho nhân viên?

Cung cấp phần thưởng như thẻ quà tặng, thêm thời gian nghỉ và ăn trưa miễn phí không chỉ là một điều có giá trị dành cho nhân viên của bạn; điều này cũng tốt cho các doanh nghiệp về lâu dài.

Một nghiên cứu năm 2018 của Genesis Associates – một công ty tuyển dụng có trụ sở tại Anh với các ngành kỹ thuật, bán hàng và phân ngành sáng tạo – khảo sát cho thấy 85% công nhân viên cảm thấy có động lực hơn để làm tốt nhất công việc khi nhận được sự khích lệ. Ngoài ra, 73% thể hiện sự hài lòng với những đánh giá là “tốt” hoặc “rất tốt” thông qua bầu không khí trong môi trường được tạo động lực. Các chương trình thưởng cho nhân viên cũng làm gia tăng lợi nhuận trung bình của một công ty lên tới 80.000 bảng Anh (khoảng 104.000 đô la) mỗi tuần, nghiên cứu cho thấy.

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

Việc tạo động lực có thể thúc đẩy bạn, cung cấp những phần thưởng cho nhân viên của bạn, đồng thời khuyến khích họ làm việc năng suất hơn. Mọi người ai cũng đều thích được đánh giá cao về những nỗ lực và việc khuyến khích là cách để cho nhân viên thấy rằng phần thưởng sẽ thật sự xứng đáng với những người làm việc hiệu quả.

Những ví dụ nào về việc tạo động lực cho nhân viên?

Vậy, những sự khuyến khích nào thực sự thúc đẩy nhân viên làm việc chăm chỉ nhất? Không phải bàn cãi, phần thưởng về tiền tệ đã giành được vị trí hàng đầu; theo khảo sát, 40% người lựa chọn tiền là động lực thúc đẩy họ nhất, 29% chọn một kỳ nghỉ miễn phí và 23% mong muốn có thêm thời gian nghỉ trong công việc. Số phần trăm còn lại gồm những phần thưởng như các bữa ăn, đồ uống và tùy chọn để kết thúc sớm một ngày làm việc.

Mặc dù sự khuyến khích dựa trên hiệu suất cá nhân của nhân viên có thể mang lại những phần thưởng có giá trị hơn, cuộc khảo sát của Genesis cho thấy rằng 71% người lao động lại ưa thích sự khuyến khích dựa trên nỗ lực của nhóm. Patrick Bell, giám đốc điều hành của Genesis Associates, cho biết điều này có khả năng vì nhân viên làm việc nhằm hướng đến mục tiêu nhóm và sẽ có nhiều người giúp duy trì và phát triển động lực cao hơn trong thời gian khuyến khích. 

Tại sao nhà tuyển dụng nên tạo động lực cho nhân viên?

Nhân viên muốn được công nhận và khen thưởng cho những cống hiến của họ.

“Làm việc dựa trên sự khích lệ của nhóm, có tính trách nhiệm với tập thể; bạn không muốn để các thành viên khác trong nhóm thất vọng”, Bell nói với Business News Daily. “Do vậy, mọi người cố gắng nhiều hơn và thường đạt được kết quả tốt hơn. Sự phân chia về lợi ích một cách phù hợp là một tiêu chí rất quan trọng. Nếu quá nhiều, mọi người có thể che giấu trách nhiệm của mình; quá ít, bạn có thể mất đi lợi ích của động lực cao hơn.”

Nếu lo ngại về ngân sách của việc cung cấp phần thưởng, bạn không nhất thiết phải cung cấp các ưu đãi tiền tệ, Bell nói. Chẳng hạn, Genesis linh hoạt sử dụng các lợi ích khác, chẳng hạn như hoàn thiện công việc sớm hơn trong một ngày, kéo dài thời gian nghỉ trưa, trao tặng cúp hay đơn giản là một bức tranh trên tường kèm tên của nhân viên để tuyên dương cho sự phấn đấu của họ.

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

Bell cũng lưu ý rằng, đối với nhiều nhân viên, sự công nhận thường quan trọng hơn số tiền mặt hoặc giải thưởng. Một số người yêu thích sự công nhận trong khi những người khác có thể ngại vì điều đó. Như vậy, điều quan trọng là phải xem xét những gì sẽ thực sự phù hợp cho nhân viên của bạn. “Chúng tôi có những giải thưởng hàng tháng để tạo động lực cho thực tập sinh tốt nhất, nhà tuyển dụng tốt nhất và đội ngũ ấn tượng của tháng”, Bell nói. 

Một lựa chọn khác cho việc tạo ra sự khuyến khích chính là sự thăng tiến, tức là cung cấp cho nhân viên một chức danh mới. Đây được xem là động lực lớn vì nó chính là minh chứng cho sự tin tưởng về tinh thần trách nhiệm đồng thời ghi nhận những nỗ lực của một cá nhân trong công việc.

Từng bước xây dựng plan tạo động lực cho nhân viên?

Việc tạo động lực không khó nếu bạn tiếp cận nó một cách chính xác. Một cách thức tốt để bắt đầu là hỏi nhân viên của bạn về những mong muốn nào họ có thể thích. 

Bạn cũng nên đặt ra những tiêu chuẩn và tính khả thi về hiệu quả cho mỗi phương án. Sau đây là những cách thức giúp bạn dễ dàng hơn trong việc tạo lực:

Tạo môi trường làm việc thân thiện và giao tiếp tích cực

Nhân viên của bạn dành một lượng lớn thời gian của cuộc sống của họ để làm việc trong văn phòng. 

Vì vậy, hãy cố gắng làm cho mọi trường làm việc nhân sự trở nên vui vẻ và hấp dẫn nhất. Bạn có thể khiến bầu không khí trở nên thú vị hơn với những câu chào hỏi thăm, kể những câu chuyện vui hay có những trò chơi mang tính kết nối.  

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

Giao tiếp tích cực được xem là chìa khóa quan trọng để bạn có thể nắm bắt tốt những mong muốn của nhân viên, thấu hiểu họ để đưa ra những giải pháp tạo động lực tốt nhất. Hãy dành ra một khoảng thời gian ngắn mỗi ngày để chia sẻ, trao đổi với nhân viên; thảo luận để nhận thấy mối quan tâm và những vấn đề nào họ đang gặp phải. Mọi người giao tiếp tại nơi làm việc và đó có lẽ là điều dễ dàng nhất bạn có thể làm với nhân viên của mình. 

Công nhận thành tích, khen thưởng và đưa ra sự khuyến khích về động lực

Mọi người đều muốn được công nhận cho những gì họ đã làm; bất kể đó là cho một công việc hoặc thành tích cá nhân. Việc được thừa nhận năng lực từ người quản lý sẽ có ý nghĩa rất lớn đối với nhân viên. 

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

Một số nhân viên có thể thích sự khuyến khích về hiện kim; trong những trường hợp này, cách tốt nhất là ghi chú những ưu đãi đó vào ngân sách hoặc lập quỹ cho họ. Bạn cũng có thể tạo ra một số biện pháp để theo dõi hiệu suất làm việc của nhân viên. Tuy vậy, không phải lúc nào phần thưởng tiền tệ cũng quan trọng vì đôi khi, một cái ôm, một cái bắt tay, một ánh nhìn hay một nụ cười đều là sự động viên, sự ghi nhận đặc biệt đối với những cố gắng của nhân viên trong công việc. 

Đưa ra sự khuyến khích là cách tạo động lực tuyệt vời nhất không những giúp nhân viên yêu công việc của mình, tự hoàn thiện mình trong kỹ năng, tác phong làm việc chuyên nghiệp, mà còn phát triển hóa mô hình hoạt động lâu dài của công ty.

Tạo mục tiêu phát triển cho nhân viên

Các nhà quản lý nhân sự nên đảm bảo rằng công ty có tầm nhìn và kế hoạch phát triển cho chính tổ chức/doanh nghiệp và mỗi nhân viên. Nhân viên họ cần một người lãnh đạo có thể đánh giá, nhận xét và định hướng phát triển lâu dài cho họ. Do đó, nhà quản lý nhân sự cần thiết lập những lộ trình nghề nghiệp vì đó là cơ sở giúp nhân viên có thể theo dõi, tự nhìn nhận khả năng và phát huy tối đa những nỗ lực của bản thân. 

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

Ngoài ra, việc tạo mục tiêu phát triển còn là cơ hội giúp nhân viên bộc lộ sức sáng tạo để thực hiện các công việc. Họ biết được mình sẽ phải làm gì, mình sẽ trở thành ai từ đó có động lực mà phấn đấu. Đồng thời, điều này cũng tạo ra sự cam kết đồng hành trong hành trình tạo ra các giá trị cho một tổ chức/doanh nghiệp.

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

Xem thêm việc làm Developers hàng đầu tại TopDev