Home Blog Page 137

Cách Sử Dụng Go Modules

Cách Sử Dụng Go Modules

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

Giới thiệu về Go Mod

Để quản lý các modules trong Go một cách tiện lợi và dễ dàng hơn, từ phiên bản Go 1.11 đội ngũ Go đã cho ra mắt Go Modules.

Chúng ta có thể sử dụng Go Modules, gọi tắt là Go Mod để install các gói module một cách tự động khi chúng ta thực hiện thực thi chương trình.

  10 Add-on Google Sheets phải có dành cho các Recruiters

  10 lý do cho thấy tại sao bạn nên theo học ngôn ngữ lập trình Java

Nếu không có Go Modules thì anh em có nhớ mỗi lần clone project về để tham khảo là phải sử dụng lệnh “go get” để tải thư viện, rất chi là mất thời gian luôn, nếu project ít thư viện thì không nói, project mà sử dụng nhiều module thư viện thì tải về bằng “go get” sẽ rất là nản.

Sử dụng Go Mod

Anh em có thể tải code tham khảo và thực hành với project Go ở đường link sau đây: Github

Project trên mình xây dựng trong GOPATH với link hướng dẫn chi tiết tại: https://anhlamweb.com/bai-viet-70/xay-dung-rest-api-co-ban-trong-golang.html

Và giờ từ project đó mình sẽ chuyển qua dùng Go Modules để quản lý các module thư viện dễ dàng hơn nha.

Anh em có thể để ý, sau khi clone project về với đường link Git ở trên thì có 2 file go.mod và go.sum.

go.mod : Định nghĩa đường dẫn của các module.

go.sum: Để lưu vết version của thư viện mà project đang sử dụng.

Anh em nhớ check lại version go mà mình đang sử dụng nhé, nếu Go 1.11 trở lên thì mới có Go Modules nhé.

Với việc sử dụng Go mod, đường dẫn tới project phải nằm ngoài thư mục src của GOPATH hoặc anh em có thể xóa biến môi trường của GOPATH đi luôn cũng được.

Bước 1: sau khi clone project về nếu anh em muốn chạy ngay chương trình thì cứ việc chạy lệnh go run main.go là được, go mod sẽ tự động tải các gói module về cho anh em luôn.

Bước 2: Bước này anh em muốn tự tay mình biểu diễn kỹ thuật, thì hãy xóa go.mod và go.sum đi sau đó chạy lệnh:

go mod init

Sau khi chạy lệnh trên thì file go.mod được khởi tạo.

Nội dung trong file go.mod

module github.com/PhongVX/golang-rest-api

go 1.12

require github.com/gorilla/mux v1.7.3 // indirect

Bước 3: Chạy chương trình và tự động tải các module bằng lệnh:

go run main.go

Sau khi chạy chương trình thì go.sum sẽ được tạo ra, lưu vết version của các module sử dụng trong project.

Nội dung trong file go.sum

github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=

github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=

Sau khi ứng dụng đã chạy, anh em có thể tham khảo bài viết này https://anhlamweb.com/bai-viet-70/xay-dung-rest-api-co-ban-trong-golang.html để test lại các API nhé. Chúc anh em thành công.

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

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

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

Cách làm nổi bật mục Kỹ năng trong CV của bạn

cv it
cv it

Một CV hoàn chỉnh cần đảm bảo các nội dung cần thiết. Mục kỹ năng được xem là 1 trong 3 yếu tố quan trọng nhất mà nhà tuyển dụng khai thác ở ứng viên. Việc trình bày kỹ năng không chỉ đơn thuần dừng lại ở việc liệt kê. Nó còn đòi hỏi ứng viên cần nắm bắt tốt các khía cạnh khác để CV đạt hiệu quả. Cùng TopDev theo dõi bài viết sau để tìm ra cách thức giúp làm nổi bật mục kỹ năng trong CV của bạn.

Phần kỹ năng trong CV có thật sự quan trọng?

Nhà tuyển dụng chỉ cần 3-5s để phân loại chất lượng CV IT của bạn. Nó ngắn hơn các loại văn bản dài như sơ yếu lý lịch cho IT,…Điều đó đồng nghĩa cơ hội để bạn tạo ấn tượng là hết sức cạnh tranh.

cv it
Kỹ năng có thật sự quan trọng trong CV IT

Nếu không biết tạo điểm nhấn, đặc biệt đối với các vị trí cao hơn như Senior Developer, CV của bạn sẽ bị quên lãng.

Phần kỹ năng là phần rất quan trọng. Nó chiếm phần trăm lớn sự kỳ vọng mà mọi nhà tuyển dụng tìm kiếm ở ứng viên. Do vậy, việc trình bày, chọn lọc các kỹ năng cũng cần phải thông minh và có chiến lược. Đừng để CV IT của bạn trở nên không có giá trị. Và tất nhiên, bạn sẽ bị out khỏi vòng phỏng vấn đấy!

Những điều cần lưu ý khi trình bày kỹ năng trong CV

Có thể bạn có rất nhiều kỹ năng. Thế nhưng, điều này không có nghĩa bạn có thể phô trương hết chúng vào trong CV của mình. Với trường hợp là CV cho sinh viên IT mới ra trường, có thể bạn còn thiếu sót.

Xem thêm các vị tri tuyển dụng IT nổi bật tại Success  Software Services

Tuy nhiên, khi apply các vị trí khác thì CV Junior Developer, Senior Developer, Mobile App Developer thì CV IT của bạn cần phải tập trung vào các kỹ năng chuyên sâu hơn. Vì vậy, hãy lưu tâm những tips sau đây:

Cụ thể hóa và trình bày các kỹ năng ứng với vị trí công việc 

Mục đích quan trọng của phần kỹ năng là thuyết phục nhà tuyển dụng bạn phù hợp với vị trí ứng tuyển. 

Vì vậy, chỉ những kỹ năng quan trọng đến vị trí ứng tuyển thì mới nên hiện diện trong list kỹ năng CV. Ví dụ như đối với CV Senior Developer, bạn nên lựa chọn các kỹ năng chuyên sâu về công nghệ như các ngôn ngữ lập trình, viết code, và các kiến thức có liên quan.

Đồng thời, viết CV giúp bạn định hình và có những trải nghiệm tốt hơn. Trường hợp bạn ứng tuyển các vị trí khác như freelancer it hay Senior Developer đều sẽ đạt hiệu quả ứng tuyển cao hơn.

Tạo CV IT chuẩn ATS miễn phí trên TopDev

Linh hoạt trong việc phân chia các kỹ năng

cv it
Việc linh hoạt trong việc phân chia các kỹ năng có ý nghĩa rất quan trọng

Hãy chia các kỹ năng của bạn thành từng các mục nhỏ ứng với các đặc trưng chuyên môn khác nhau. Bạn có thể liệt kê và phân chia các kỹ năng về ngôn ngữ lập trình; các nhóm kỹ năng về phần mềm. Chính việc phân loại giúp bạn hiểu rõ hơn về vị trí. Đồng thời, nhà tuyển dụng sẽ đánh giá cao hơn về năng lực phân tích của bạn.

Tập trung vào các kỹ năng quan trọng theo tần suất

Đây là cách ứng viên nhấn mạnh các kỹ năng quan trọng bằng cách lặp lại các kỹ năng. Tất nhiên, việc “rải” từ khóa về kỹ năng cần ứng viên phải khéo léo và tinh tế. Bạn có thể phân theo từng mục và giới hạn xuất hiện để đảm bảo các kỹ năng không bị trùng lặp quá nhiều lần.

Cụ thể bạn có thể liệt kê kỹ năng trong phần đầu – phần giới thiệu và phần kinh nghiệm làm việc. Từ khóa về kỹ năng rất quan trọng để nhà tuyển dụng kết luận đâu là điểm mạnh của bạn. Tuy vậy, tần suất hoàn hảo nhất của một kỹ năng chỉ nên từ 2-3 lần.

Ứng viên không nên quá lạm dụng. Đặc biệt, kỹ năng được lặp lại phải thật sự phản ánh chính xác năng lực của bạn. 

Lời kết

Kỹ năng là một yếu tố quan trọng xét về nội dung CV. Một CV sẽ mất đi giá trị tổng thể nếu thiếu đi mục kỹ năng. TopDev hy vọng với những chia sẻ thông qua bài viết, các ứng viên sẽ biết cách điều chỉnh và hoàn thiện chuyên mục kỹ năng của CV IT, giúp CV của mình ghi điểm tuyệt đối với nhà tuyển dụng.

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

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

4 tips học Java cơ bản nhanh nhất dành cho Beginner Developer

java cơ bản
4 tips học Java cơ bản nhanh nhất dành cho Beginner Developer

Tác giả: Back To Back SWE

Cách tôi bắt đầu làm quen với Java cơ bản

Bài viết hôm nay của tôi sẽ chia sẻ với các bạn những tips để lập trình Java, android cũng như những thứ khác một cách nhanh nhất. Giới thiệu qua một chút về bản thân thì cho đến 2 năm trước, tôi vẫn chưa biết gì nhiều về lập trình cả. Lúc đó trong đầu tôi xuất hiện rất nhiều các ý tưởng về lập trình app nhưng không biết nên bắt đầu từ đâu cả. Vậy là tôi tìm kiếm rất nhiều các nguồn tài liệu để nghiên cứu về lập trình từ các video, đến sách vở và tham gia thêm các khóa học.

Tôi đăng ký khóa học Java online trong 1 tháng và học android trong 2 tháng. Sau khi kết thúc khóa học, tôi đã tự build được app đầu tiên trong sự nghiệp của mình với những idea mà mình vẫn luôn ấp ủ trước giờ. Tuy nhiên, nhìn lại quá trình này tôi rút ra một số kinh nghiệm để có thể làm việc tốt hơn khi bắt đầu với Java cơ bản.

học java online
Học java cơ bản giúp ích rất nhiều cho quá trình lập trình sau này

Những kinh nghiệm để học Java cơ bản hiệu quả

1. Đừng vội vàng khi bắt đầu học Java cơ bản

Nhiều bạn nghĩ rằng càng đi nhanh việc học sẽ càng đạt kết quả sớm hơn. Tuy nhiên sự thật là bạn không nên vội vàng khi học lập trình. Học một cách chậm rãi sẽ khiến bạn có nhiều thời gian để tiếp thu kiến thức cũng như nắm vững những vấn đề về Java cơ bản. Sau đó bạn có thể tăng tốc quá trình học một cách nhanh nhất có thể khi đã có căn bản. Có nhiều bạn khi mới bắt đầu học chỉ lướt sơ về kiến thức với một số điểm nổi bật, vì thế mà bạn không thể nắm được bức tranh tổng thể về Java cơ bản.

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

Nếu học theo kiểu sơ sài như thế này, nó sẽ trở thành thứ ngăn cản bạn học thêm các ngôn ngữ lập trình mới và chỉ khiến quá trình tiếp thu kiến thức ngày càng chậm đi mà thôi. Vì vậy hãy dành nhiều thời gian học tập khi mới bắt đầu để đẩy tốc độ học về sau. Java cơ bản gần như là kiến thức tối quan trọng mà bạn cần nắm chắc để không mắc sai lầm về sau cũng như học nhanh hơn sau này.

2. Tập trung nghiên cứu các lỗi sai bạn mắc phải

Việc mắc lỗi luôn xảy ra khi mới bắt đầu học lập trình, tuy nhiên nhiều dev chỉ đơn giản bỏ qua những dòng code lỗi và viết mới. Bạn thật sự rất cần tìm hiểu về những code bị lỗi, để có thể nghiên cứu và tìm ra nguyên nhân tại sao code đó lại không chạy được, vấn đề đang nằm ở đâu, có như vậy bạn mới tìm ra được những dòng code tốt nhất cho chương trình của mình.

Hơn nữa, nếu bạn không tìm hiểu nguyên nhân và sửa lại, chương trình bạn viết ra sẽ ngày càng nhiều code hơn. Nó là một bản chắp vá của rất nhiều lỗi nhỏ khác nhau. Đến một lúc nào đó, bạn sẽ hoàn toàn không thể quản lý được những gì bạn viết ra nữa. Nó sẽ trở thành cơn ác mộng cho việc sửa chữa hay để người khác quản lý được chương trình này. Nghe có vẻ khó hiểu đúng không? Bạn phải thật sự đang coding và đọc những dòng này thì mới hiểu những gì tôi đang nói đó.

Tìm Java job lương cao trên TopDev ngay!

học java cơ bản
Để học tốt java, bạn nên có sự đầu tư và nghiên cứu bài bản

3. Cố gắng nắm rõ và bao quát được nhiều bài học

Để học tập hiệu quả hơn, bạn nên cố gắng xem qua mỗi một bài học có liên quan đến Java cơ bản. Ngay cả khi bạn đã học thuộc lòng chúng hay đang cầm tài liệu trên tay, bạn vẫn nên cố gắng xem qua mỗi bài học và hiểu rõ về mọi khía cạnh của chúng. Vì chẳng ai biết được một lúc nào đó, khi đang coding và build program một cách trơn tru, bạn lại đột nhiên quên mất một chi tiết nhỏ nhưng rất cần thiết để hoàn thành được chương trình một cách hoàn hảo nhất. Vì quên kiến thức bạn phải quay lại từ đầu để tìm cách và việc này chắc chắn sẽ mất rất nhiều thời gian.

Hãy đảm bảo rằng bạn có đủ thời gian để xem qua các bài học. Đó cũng là cách để bạn có thể học nhanh nhất. Bạn có thể hiểu được sự liên kết của những kiến thức Java cơ bản trong số rất nhiều các ngôn ngữ lập trình khác.

  10 lý do cho thấy tại sao bạn nên theo học ngôn ngữ lập trình Java
  11 mẹo đơn giản để tăng hiệu suất Java cấp tốc

4. Dành thời gian luyện tập coding mỗi ngày

Bạn nên lên lịch để luyện tập coding mỗi ngày, bạn có thể dành từ 30 phút đến 2 giờ để code. Khi mới bắt đầu học lập trình, tôi dành ra 4 đến 5 tiếng mỗi ngày để tập tành làm việc, kể cả là phải thức khuya. Thật sự thì tôi không khuyến khích bạn làm quá nhiều việc vì nó sẽ không hiệu quả. Tôi nghĩ bạn nên dành ra 30 phút đến 1 tiếng mỗi ngày để thực hành 1 hoặc 2 bài tập liên quan đến học Java cơ bản là tốt rồi.

Chẳng hạn như với khóa học Java online mà tôi đăng ký với thời gian học trong 1 tháng. Trong suốt 1 tháng đó, mỗi ngày có 3 video được gửi đến email của tôi, tôi mất 15 phút để xem qua chúng. Đây thật sự là phương pháp hiệu quả để tôi nâng cao tay nghề của mình. Tôi nghĩ rằng việc học tập và thực hành mỗi ngày là cần thiết và bạn nên sắp xếp thời gian hợp lý để làm điều đó. Hãy xem việc học như một sở thích và đừng quá đặt nặng áp lực phải làm cho tốt. Mọi thứ sẽ được cải thiện dần dần.

Bên cạnh đó, việc nắm chắc các kiến thức Java cơ bản cũng giúp bạn làm việc tốt hơn hoặc khi chuyển sang làm việc ở lĩnh vực khác cũng dễ dàng thích nghi và học hỏi hơn. Chẳng hạn như hiện nay, tester đang là một trong những hot job được nhiều người nhắm đến. Lương Senior Tester luôn nằm trong hạng top đối với các công việc khác của ngành IT.

Kết luận

Để học tập tốt cũng như làm việc hiệu quả hơn, các dev nên biết cách sử dụng các tip để làm quen với việc học và thực hành. Nó không chỉ mang lại kết quả khả quan hơn mà còn giúp bạn tiết kiệm được kha khá thời gian của mình đấy. Và nhờ kỹ năng làm việc tốt bạn sẽ tìm được công việc yêu thích của mình ở môi trường chuyên nghiệp như Gear Inc. chẳng hạn.

Gear Inc. Vietnam tuyển dụng hiện đang được đánh giá là một trong những cơ hội làm việc hấp dẫn dành cho các developer. Môi trường làm việc hiện đại, đội ngũ phát triển đạt tầm quốc tế cùng với sự gắn kết giữa các đồng nghiệp sẽ giúp bạn dễ dàng học hỏi và tích lũy kinh nghiệm làm việc. Sự năng động và phóng khoáng của môi trường sáng tạo game chắc chắn sẽ khiến bạn thấy thoải mái hơn khi làm việc tại Gear Inc. Đây là những đánh giá được ghi nhận về Gear Inc review.

Bài viết được transcript từ video gốc tại đây

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

Xem thêm việc làm Tuyển dụng Java hấp dẫn tại TopDev

Phỏng vấn tác giả Proxyman: Từ side project thành full-time business

Phỏng vấn tác giả Proxyman

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

Bắt đầu từ một pet product để giải quyết những vấn đề cá nhân gặp phải trong quá trình làm việc, bạn Nghĩa Trần đã dày công theo đuổi và xây dựng Proxyman trở thành một sản phẩm chuyên nghiệp thu hút được hàng nghìn user đến từ khắp nơi trên thế giới, đem về doanh thu cực khủng.

  13 điều giúp ứng viên... rớt phỏng vấn xin việc

Bài phỏng vấn dưới đây là những chia sẻ hết sức thú vị và bổ ích của Nghĩa về kinh nghiệm cũng như quá trình xây dựng và phát triển Proxyman.

Phỏng vấn tác giả Proxyman: Từ side project thành full-time business

Xin chào Nghĩa, cảm ơn Nghĩa đã nhận lời mời phỏng vấn ngày hôm nay. Nghĩa có thể giới thiệu qua một tí về bản thân cũng như về Proxyman với các độc giả được không?

Mình là Nghĩa Trần. Hiện tại mình đang là macOS Developer ở Toggl.com

Cơ bản thì ý tưởng về Proxyman chỉ đơn giản là giải quyết cái ức chế của mình khi xài Charles Proxy mà mình “bị”, “phải” xài hằng ngày lúc mình còn ở Zalora Vietnam.

  • Nếu bạn đã từng xài Charles Proxy, Wireshark hay Fiddler để bắt được HTTP/HTTPS traffic từ mac hoặc iPhone để debug dễ dàng thì bạn sẽ biết Proxyman là gì ;]
  • Còn nếu chưa, thì Proxyman là một HTTP Debugging Proxy app, dùng dễ capture / intercept / manipulate HTTP / HTTPS requests / response từ macOS, iPhone, Android và cả Simulator.

Một vài selling-point của Proxyman là:

  • Native macOS app
  • Dễ xài, không cần Google để setup certificates.
  • Đầy đủ features như Charles Proxy (Hopefully)
  • Và phải nhanh (ai cũng muốn nhanh nên app phải nhanh ;]

Bạn build Proxyman lâu chưa? Trước Proxyman thì bạn có product nào khác nữa không? Bạn làm team hay một mình?

Proxyman là pet product mà mình theo đuổi lâu nhất : D hơn 1 năm và vẫn chưa có ý định chán =)) (Hy vọng là thế)

Version Prototype đầu tiên của Proxyman được ra mắt vào ngày Aug 3, 2018, và bản Stable gần nhất là Proxyman 1.7.2 Oct 24, 209. Tổng cộng có tất cả 46 releases.

Ngày launch app bất ngờ trên Product Hunt là hôm March 31st, 2019. Do một bạn nào đó tự post và tag mình vào 😀 nên phải cuốn theo chiều gió và coi như làm hôm launch chính thức, dù mình vẫn định delay thêm vài tháng cho để có thêm thời gian fix thêm một mớ bugs.

Launch trên Setapp ngày Jun 1st, 2019 và cũng là ngày launch cái licensing system.

Trước Proxyman thì mình chỉ build vài product chơi, chủ yếu là học code macOS. Ví dụ

Cả 2 project hiện tại đã stop, vì Uber không còn ở VN và Artify cũng đã gần xong 😀

Proxyman thì mình là người build từ những ngày đầu tiên. Hiện tại thì có bạn gái mình tham gia viết blog và đảm nhiệm phần users acquisition, Huy – TablePlus là co-founder sau này giúp mình có thêm business insight về users và SaaS product.

Về pricing model thì bạn dựa vào đâu để định mức giá? Và việc distribute nó trên Setapp có khiến bác thay đổi gì về pricing không?

Về Pricing thì mình tham khảo đối thủ chính của Proxyman là

  • Charles Proxy (https://www.charlesproxy.com)
  • Một số apps (Sketch, NSSurge, TablePlus, Postico) có customer chủ yếu là individual / SMEs.

Giá License thường tầm $49 / năm nên mình chọn mức này. Fun fact là với giá $49 này, mình cũng bị một vài users complain về việc quá mắc, mà feature lại chưa đầy đủ :)) nhưng kệ, cứ ra feature và giữ standard cao.

Ngoài ra vẫn có kha khá users (developers) có 2 máy, và việc mua 2 license ($90) thì không khả thi, nên mình offer thêm Combo với mức giá $59. Team license (>= 3) thì $39.

Ngoài ra, vẫn có những đối thủ cộm cán như Fiddler, Wiresharke, Debookee …. tuy nhiên customers chủ yếu là enterprise.

Việc distribute lên Setapp không ảnh hưởng gì tới mức license hiện tại cả. Vì 80% users của mình không xài Setapp. User vẫn thích mua license và được support trực tiếp từ mình khi có bug hay feature request. Mục đích của việc distribute lên Setapp là giúp tăng độ trust của Proxyman.

Bạn có run ads hay gì để marketing cho nó không? Hay để… hữu xạ tự nhiên hương?

Hiện tại mình không run ads. Tất cả chi phí dành cho ads hay marketing hiện là 0. Tất cả điều nhờ “word of mouth”.

Approach này có thể sẽ chậm lúc ban đầu, nhưng khá hiệu quả để build trust của users. Vì thường mọi người sẽ thích xài app khi bạn bè mình giới thiệu hơn là xài một cái app thấy trên Ads. Cách này cũng rất dễ convert một user thành loyaty user (purchased license, cuồng app, tweet Proxyman và khoe với mọi người). Họ đã trờ thành local influencers, và Proxyman cũng từ từ được biết tới.

Ngoài ra mình cũng chú trọng tới viết blogs và trả lời nhiều câu hỏi liên quan tới SSL Proxying, debugging trên StackOverflow, … và có link lại Proxyman.

Ngoài ra, 1 chiến thuật khác để acquire users là quick responsiveness. Mình sẽ support trong vòng 1-2 tiếng. Nếu user report 1 bug trên Github, Twitter, Gitter, thì mình sẽ fix và gửi bản hotfix cho user ngay lập tức. Cách này rất hiệu quả ở giai đoạn đầu của product, vì chứng tỏ product mình rất active, có hot-fix build thì user nó có thể tiếp tục job của nó mà không cần phải đợi qua tuần cho bản Stable release.

Kết quả là có rất nhiều users appreciated, và họ rất thích được chat với founder của products. Chắc vì họ cũng painful khi Charles Proxy (product họ đang xài) không có 1 kênh chính thức nào để support họ. Và cũng kha khá user mua license để cảm ơn sau khi mình support họ 😄

Tất cả những điều trên điều giúp mình acquire nhiều users hơn và cũng là go-to-market strategies của Proxyman hiện tại.

Về tình hình revenue thì hiện tại như nào, nếu tiện thì Nghĩa có thể chia sẻ một tí được không?

Revenue hiện tại tầm “chưa đến $5K MRR” từ License + Setapp. Cũng không nhiều so với những app SaaS khác, nhưng cũng đủ cho thời điểm hiện tại.

Plan của Proxyman là long term nên mình vẫn tin là Proxyman sẽ bump lên được vài năm tới. Thực tế là, Charles Proxy cũng mất 15 năm mới lên được vị trí như bây giờ, và Charles Proxy team chỉ có 1 người 😀

Khi build sản phẩm này thì bạn có từng cân nhắc giữa chuyện có nên open source nó for free và kiếm tiền từ nó không?

Kha khá users email hỏi về việc mình Open Source, tuy nhiên mình không cân nhắc approach này. trong thời điểm hiện tại (Cả founder của Insomnia cũng khuyên mình OSS).

Thật ra mục đích đầu tiên ở Proxyman là thử sức với những technical challenges mới. Mình có vài năm code iOS, cơ bản công việc vẫn chỉ là app listing, social apps, mọi thứ đã có sẵn và điều này khiến mình cảm thấy rất boring.

Charles Proxy không có alternative nào và có rất nhiều người đang tìm alternative, nhưng bất lực, nên mình nghĩ có thể đây là cơ hội để mình disrupt, kiểu Trello vs Jira 😀

Mình cũng cân nhắc chuyện bán license. Vì đó là cách để thuyết phục users là Author của Proxyman là nghiêm túc trong việc làm product.

OSS sợ mọi người thấy code dỏm, user bỏ đi 😄

Nói về technical challenges, Nghĩa có thể chia sẻ thêm về những challenge bạn đã gặp phải trong quá trình làm Proxyman được không?

Một vài challenges trong Proxyman là:

  • Build 1 app macOS native, developer tool.
  • Làm sao để buit được Intuitive UI? Không cần train vẫn mà naive users vẫn có thể xem được HTTPS Response? In fact, những ngày đầu mình xài Charles Proxy và Wireshark, thì gần như user phải biết mình phải làm gì, 90% (cả mình) cũng phải google cách sử dụng. Xài app mà cũng phải google cách xài LOL.
  • Làm sao build được 1 cái Proxy server? Làm sao parse được Raw HTTP Message?
  • Làm sao biết được request đó đi ra từ client nào?
  • Làm sao xem được HTTP Response? Cả HTTPS?
  • Làm sao trở thành MitM app, và không bị client reject the certificates?
  • Làm sao generate chain certificate on the fly?
  • Làm sao xem được requests từ iPhone, iOS Simulator và Android?
  • SSL Handshake?
  • Làm sao implement được “Privileged Helper Tool” để override system HTTP/HTTPS Proxy trên macOS?
  • WebSocket debugging, Advanced features (Local Map, Breakpoint, External Proxy, Network Throttling, …)?
  • Và rất rất nhiều thứ mình không có cơ hội làm nếu là iOS dev 😀

Tóm lại, code developer tool nó nhều challenges và hẳn là fun hơn 😀

Khi quyết định hướng kiếm tiền từ nó, bạn có từng phải cân nhắc giữa chuyện “bao nhiêu là đủ” cho việc xài free và bản trả phí không? Bạn có nghĩ tới chuyện sẽ bị user nó abuse cái free trial không?

Mình cũng cân nhắc rất nhiều về Business Model cho Proxyman: Premium, Freemium hay Trial.

Cuối cùng thì mình chọn Freemium. Cơ bản tất cả features (basic và advanced features) điều free và xài thoải mái để hoàn thành công việc hơn là phải mua license trước.

Bản Paid Proxyman chỉ unlock một vài cái cơ bản như Multiple-Tabs, số pin item, số rule trong Local Map, Breakpoint, …

Mục đích là để users cho dù xài bản free, vẫn có thể hoàn thành công việc của họ mà không có bất kỳ cản trở nào. Khi họ enjoy, làm được việc, thì họ sẽ thích app và mua license. Hạn chế việc làm user cảm thấy ức chế khi xài.

Một vài ví dụ, Charles Proxy bản free sẽ tự kill cái session trong 30p, nghĩa là sau 30p, sẽ mất hết 😀 rất ức chế.

Kha khá users mua app ngày từ đầu, vì họ vui mừng tìm được 1 app thay thế Charles Proxy mà họ đã xài một cách “chịu đựng” vài năm.

Với kinh nghiệm từ Proxyman, thì bạn đánh giá tỉ lệ giữa free user và paid user là như nào? và conversion rate ở đây như nào? Thị trường nào có tỉ lệ paid user cao nhất? Và so với thị trường VN thì sao?

Convert rate của Proxyman hiện tại là 1-2%. US và EU là 2 thị trường có user mua nhiều nhất. VN và ASIA nói chung chỉ có free users, không có paid users hiện tại.

Proxyman có khoảng 4k monthly users và khoảng 250-350 daily user. Returned user là ~80% users. US + EU chiếm khoảng 95%, còn lại China và một chút Southern-ASIA.

Phỏng vấn tác giả Proxyman: Từ side project thành full-time business

Có vài điểm mình để ý là Nghĩa có đề cập đến trong quá trình build và marketing cho Proxyman, nghe có vẻ khá thú vị và mình muốn đào sâu vào khía cạnh này một tí như việc làm thế nào để build được intuitive UI, hay như việc tập trung quảng bá bằng cách educate người dùng thông qua blog, hay trả lời câu hỏi trên StackOverflow. Nghĩa có thể chia sẻ về con đường mà bạn đã trải qua để có được những kinh nghiệm này được không?

Để trả lời được câu hỏi làm sao build được intuitive UI thì rất khó trả lời, vì nó không có câu trả lời cuối cùng nào cả:

  • Mình chỉ xài nhiều modern native app như TablePlus, Dropbox, Paw, Sublime, … và hiểu được cái Common-sense của những app native đó. Nó cũng giống như việc để design một app iOS thì cách đơn giản nhất là download nhiều features iOS app trên AppStore và xài hằng ngày. Về lâu dài gì mình sẽ hiệu được kha khá common-sense và biết được trend hiện tại.
  • Đọc Human Interface Guidelines của platform mà mình đang build. Ở macOS là https://developer.apple.com/design/human-interface-guidelines/macos/overview/themes/
  • Có 1 người high standard ở cạnh và debate về UI.
  • Những feature nào users xài nhiều nhất thì mình để ra toolbar, còn lại sẽ được hide trong Context Menu. Để users không bị choáng nếu app mình có quá nhiều buttons. Lấy ví dụ một số app theo style Windows như Pycharm, Wireshare,… sẽ có rất nhiều feature và buttons trên toolbars.
  • UI Đơn giản là quan trọng nhất.
  • Và may mắn???

Bởi vì plan của Proxyman là không dùng Ads nên cách duy nhất để reachout tới users là thông qua nhưng channels như Blog, StackOverFlow, Reddit, … Trả lời giúp mấy bạn đang bí trên StackOverflow và offer họ 1 solution tốt hơn là cách mình đang áp dụng.

Có một vấn đề mà mình và nhiều người khác cũng hay gặp phải, đó là việc giữ cho bản thân mình tập trung và có thêm động lực trong quá trình build ý tưởng của mình thành một sản phẩm hoàn chỉnh, nhất là khi gặp phải những trở ngại trong quá trình build, nó khiến chúng ta rất dễ nản chí và thậm chí là bỏ cuộc. Nghĩa nghĩ sao về điều này? Chắc bạn cũng đã từng gặp vấn đề này trong quá trình làm Proxyman?

Việc này là điều hiển nhiên nếu bạn build SaaS product và việc duy nhất có thể làm được là chấp nhận nó tiếp tục làm.

Ko có silver-bullet cho việc này. Tất cả chỉ là từ phía bạn và chỉ là bạn có muốn tiếp tục hay ko?

Mình nhớ có tới 3 giai đoạn mình cũng rơi vào thế bí toàn cục khi làm Proxyman. Ví dụ

  • Làm sao build được native Proxyman Core (MitM) và có thể xem được HTTPS Request/Response?
  • Làm sao làm được Local Map hay Breakpoint feature? Mà có thể can thiệp và chỉnh được Message on-the-fly?
  • Làm sao design được UI vừa đẹp mà cũng vừa dễ xài?

Để trả lời được mấy câu hỏi trên thì mình cũng phải làm 3-4 prototype versions cho từng vấn đề. Google đủ kiểu, đọc OSS, và code prototype. Bí quá thì tìm cách khác hoặc đi hỏi bạn bè.

Ngoài ra mình còn 1 lời khuyên là nên build MVP version cho từng feature. Đừng bao giờ expect là mình có thể làm 100% feature rồi mới release vì sẽ rất lâu, và cũng không có cái gọi là 100% hoàn hảo.

MVP version, log lại hành trình của mình lên Twitter, và làm hài lòng một nhóm nhỏ user trước khi tiếp tục code tiếp v2 là cách dễ dàng nhất để có thêm động lực làm tiếp. Vì user họ khoái, họ support mình : D

  • UI hiện tại mình là version 4. Tạm coi là được nhưng mình đang improve v5 cho phần Filter bar.
  • Proxyman core của mình cũng là 3 version, hiện tại khá stable.

Có rất nhiều bạn độc giả cũng gửi mail và message cho mình rằng họ rất quan tâm đến việc tự phát triển và phát hành sản phẩm, như những gì mà Nghĩa đã làm với Proxyman. Là một người đi trước và cũng nếm trải đủ nhiều, Nghĩa có lời khuyên gì cho các bạn không?

Mình cũng không chắc là lời khuyên của mình có hợp với mọi người hay ko. Nhưng đây là những gì mình đã và đang làm:

  • Nếu mục tiêu của product là học hỏi, thử nghiệm framework, language mới thì bạn có thề start từ ngay bây giờ. Open Source, và nếu được bạn có thể viết blog kể về journey của bạn. Hướng đi này rất hay vì bạn có thể build được reputation cho chính bạn, vừa có cả quality product để apply job sau này.
  • Nếu muốn build một product nghiêm túc thì theo mình tìm cái pain point và validate cái idea này ở global market ngày từ những ngày đầu tiên.

Có rất nhiều cách reach tới global market là bạn publish app lên Product Hunt, Reddit, Hackernews, Markerlog hoặc một kênh distributions nào đó như Setapp.

Twitter + Github làm channel chính mà make connection với những authors khác. Ví dụ Insomnia, NativeConnect, Chime, …

Rất cảm ơn Nghĩa đã dành thời gian tham gia cuộc phỏng vấn này. Chúc Nghĩa sẽ ngày càng thành công hơn nữa với Proxyman cũng như với các sản phẩm của bạn trong tương lai nhé 😀

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

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

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

Todo App ASP.NET MVC x Entity Framework

Todo App ASP.NET MVC x Entity Framework

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

Giới thiệu

Hôm nay mình sẽ chia sẻ đến các bạn về cách thực hiện Todo Web App đơn giản với ASP.NET MVC và Entity Framework. Mình không chuyên .NET hay web, nhưng mình có học qua rồi nên viết cho vui để sau này biết đâu cần lại quên.

Todo của mình sẽ có các thông tin như Name, Content, DateAdded, IsDone và UserId. UserId để xác định todo đó của user nào. App sẽ có các thao tác cơ bản như xem toàn bộ todo, xem chi tiết 1 todo, thêm, sửa, xóa todo.

Tuyển dụng ASP.NET lương cao không yêu cầu kinh nghiệm.

  Giới thiệu Web service – SOAP, WSDL và ASP.NET Web Service cơ bản

Tạo project

Mình sẽ tạo một project ASP.NET MVC, .NET Framework hiện tại là 4.7.2, chọn Authentication là Individual User Accounts.

Sau khi tạo project xong, các model và controller quản lý việc đăng nhập đã được tạo sẵn, mình sẽ không mất công tạo lại nữa, mình cũng chỉ cần đăng nhập thôi nên không cần thêm sửa gì.

Các trang như About, Privacy mình không dùng đến nên xóa nó đi (nhớ xóa cả action của nó trong HomeController.cs), xóa luôn các link trên thanh nabbar trong ~/Views/Shared/_Layout.cshtml.

Enable migraitons

Mình sẽ sử dụng Code-First workflow để tạo database, đỡ phải viết query dài dòng. Do lúc tạo project, mình đã chọn Authentication rồi nên nó sẽ tự tạo cho mình các cái table cần thiết để quản lý user. Vậy nên, mình sẽ enable migrations rồi add migration authentication trước.

Enable-Migrations
Add-Migration InitialAuthenticationModel
Update-Database

Lúc này bạn có thể Show All Files và mở file .mdf trong folder App_Data, bạn sẽ thấy các table đã được tạo.

Authentication

Người dùng sẽ phải đăng nhâp để thao tác với todo vì mỗi người dùng có todo khác nhau. Mình sẽ quay lại HomeController và thêm annotation Authorize:

[Authorize]
public class HomeController : Controller
{
    // Code...
}

Lúc này khi người dùng vào trang mà chưa đăng nhập thì sẽ bị chuyển hướng đến trang đăng nhập.

Add Todo Model

Tiếp theo mình sẽ tạo Todo model với các thông tin mình đã nêu. Do Id của user là string(128) nên mình sẽ để thuộc tính UserId của Todo là string luôn.

namespace TodoWebApp.Models
{
    [Table("TodoTable")]
    public class Todo
    {
        public int Id { get; set; }

        [Required]
        [MaxLength(256)]
        public string Name { get; set; }

        [Required]
        [MaxLength(1024)]
        public string Content { get; set; }

        [Required]
        [Display(Name = "Have you done it?")]
        public bool IsDone { get; set; } = false;

        [Required]
        public DateTime DateAdded { get; set; } = DateTime.Now;

        [Required]
        [MaxLength(128)]
        public string UserId { get; set; }
    }
}

Sau khi đã có model rồi thì mình tiến hành thêm nó vào ApplicationDBContext. Mở file IdentityModels.cs và thêm vào thuộc tính todo:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public DbSet<Todo> Todo { get; set; } // Add this line
    // Code goes here...
}

Sau đó tiếp tục add migration:

Add-Migration AddTodoModel

Sau khi add migraiton, mình sẽ chỉnh sửa lại một chút. Trong khi create table, mình sẽ để mặc định cho IsDone là false và DateAdded là lấy ngày tháng hiện tại, mình sẽ sửa lại như sau:

IsDone = c.Boolean(nullable: false, defaultValue: false),
DateAdded = c.DateTime(nullable: false, defaultValueSql: "GETDATE()"),

Sau đó updata database:

Update-Database

Show Todo

Mình sẽ bắt đầu với controller trước, để lấy được data từ database, mình sẽ cần có DbContext. Mình sẽ thêm thuộc tính private vào HomeController:

private readonly ApplicationDbContext _context = new ApplicationDbContext();

Tiếp theo, trong action Index, mình cần lấy ra toàn bộ todo của user đã login, mình sẽ lấy UserId sau đó tìm todo có UserId đó trong database và return về View kèm theo ViewModel là một todo list:

public ActionResult Index()
{
    var uid = User.Identity.GetUserId();
    var todo = _context.Todo.Where(t => t.UserId == uid);
    if (todo == null)
    throw new HttpException(404, "Not found");
    return View(todo);
}

Sau đó, trong Index.cshtml, mình cho Model của nó là một IQueryable<Todo> (tương tự như list vậy) sau đó foreach và đổ data ra table, sử dụng bootstrap.

@model IQueryable<TodoWebApp.Models.Todo>

@{
    ViewBag.Title = "Home Page";
}

<h1 class="page-header">All Your Todo</h1>

<div>
    <table class="table table-bordered table-hover">
        <thead>
        <tr>
            <th>Name</th>
            <th>Done</th>
            <th>Edit</th>
            <th>Delete</th>
        </tr>
        </thead>
        <tbody>
        @foreach (var todo in Model)
        {
            <tr>
                <td>@todo.Name</td>
                <td>
                    @if (todo.IsDone)
                    {
                        <p>Done</p>
                    }
                </td>
                <td>Edit</td>   // các action này sẽ được thay thế sau
                <td>Delete</td> // các action này sẽ được thay thế sau
            </tr>
        }
        </tbody>
    </table>
</div>

Do mình chưa có data nên nó sẽ không có gì cả. Các bạn có thể test bằng cách bỏ Where() sau _context.Todo đi sau đó thêm data thủ công vào database và refresh lại trang.

View Detail

Tiếp tục, tạo action Detail và view Detail để xem thông tin chi tiết của todo. Trong action Detail sẽ nhận vào một id của todo, trong action này sẽ lấy thêm UserId để lấy được chính xác todo của user cần xem và trả về view cho người dùng.

public ActionResult Detail(int id)
{
    var uid = User.Identity.GetUserId();
    var todo = _context.Todo.SingleOrDefault(t => t.Id == id && t.UserId == uid);
    if (todo == null)
         throw new HttpException(404, "Not found");
    return View(todo);
}

Phần view thì đơn giản mình sẽ cho hiển thị thêm thông tin:

@model TodoWebApp.Models.Todo
@{
    ViewBag.Title = "Detail";
}

<div class="jumbotron">
    <h1>@Model.Name</h1>
    <p>@Model.Content</p>
    <p>Added on @Model.DateAdded.ToLongDateString()</p>
    @if (Model.IsDone)
    {
        <p>You have done this task!</p>
    }
</div>

Sau đó để xem thông tin, mình sẽ cho một đường dẫn đến action Detail kèm theo id của todo. Mình sẽ sửa lại Index.cshtml:

// Thay
<td>@todo.Name</td>

// Thành
<td>@Html.ActionLink(@todo.Name, "Detail", new { id = todo.Id })</td>

Add Todo

Để add todo, mình cần 2 action, 1 là để điều hướng người dùng đến form, 2 là để thực hiện add todo vào trong database:

public ActionResult Add()
{
    return View();
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Add(Todo todo)
{
    if (!ModelState.IsValid) return View(todo);
    todo.UserId = User.Identity.GetUserId();
    _context.Todo.Add(todo);
    _context.SaveChanges();
    return RedirectToAction("Index");
}

Action Add khi thêm todo thì sẽ gọi action Add có phương thức POST và truyền model vào. Mình sẽ build form Add như sau:

@model TodoWebApp.Models.Todo
@{
    ViewBag.Title = "Add todo";
}

<h2 class="page-header">Add Todo</h2>

@using (Html.BeginForm("Add", "Home", null, FormMethod.Post, new { @class = "form-group" }))
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary()

    @Html.LabelFor(t => t.Name)
    @Html.TextBoxFor(t => t.Name, new { @class = "form-control" })
    @Html.ValidationMessageFor(t => t.Name)
    <br />

    @Html.LabelFor(t => t.Content)
    @Html.TextBoxFor(t => t.Content, new { @class = "form-control" })
    @Html.ValidationMessageFor(t => t.Content)
    <br />

    <div class="checkbox">
        <label>
            @Html.CheckBoxFor(t => t.IsDone)
            @Html.LabelFor(t => t.IsDone)
        </label>
    </div>

    @Html.HiddenFor(t => t.UserId, new { @Value = "default_user_id" })

    <input type="submit" class="btn btn-primary" value="Submit" />
}

Mình có để HiddenFor là để tránh việc validate bị lỗi do trường UserId bị null do mình có để Data Annotation là Required trong model Todo.

Edit Todo

Sẵn làm form add todo thì làm luôn form edit todo vì chúng khá giống nhau:

public ActionResult Edit(int id)
{
    var uid = User.Identity.GetUserId();
    var todo = _context.Todo.SingleOrDefault(t => t.Id == id && t.UserId == uid);
    if (todo == null)
        throw new HttpException(404, "Not found");
    return View(todo);
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Todo todo)
{
    if (!ModelState.IsValid) return View(todo);
    var uid = User.Identity.GetUserId();
    var todoInDb = _context.Todo.SingleOrDefault(t => t.Id == todo.Id && t.UserId == uid);
    todoInDb.Name = todo.Name;
    todoInDb.Content = todo.Content;
    todoInDb.IsDone = todo.IsDone;
    _context.SaveChanges();
    return RedirectToAction("Index");
}

Và form edit thì cũng tương tự, mình chỉ sửa action của BeginForm() thành “Edit” thôi. Tiếp theo mình cần dẫn người dùng từ index đến chỉnh sửa todo và truyền kèm id của todo.

// Thay
<td>Edit</td>

// Thành
<td>@Html.ActionLink("Edit", "Edit", new { @id = todo.Id })</td>

Delete Todo

Phần Delete cũng khá đơn giản, mình chỉ cần truyền Id của todo được nhấn vào action và tìm xem có không, có thì delete đi.

public ActionResult Delete(int id)
{
    var uid = User.Identity.GetUserId();
    var todo = _context.Todo.SingleOrDefault(t => t.Id == id && t.UserId == uid);
    if (todo == null)
        throw new HttpException(404, "Not found");
        _context.Todo.Remove(todo);
        _context.SaveChanges();
        return RedirectToAction("Index");
}

Và sửa Index như sau:

// Thay
<td>Delete</td>

// Thành
<td>@Html.ActionLink("Delete", "Delete", new { @id = todo.Id })</td>

Tổng kết

Như vậy là mình đã có thể tạo được một App Todo đơn giản rồi. Mình chỉ làm project nhỏ này cho vui thôi, chưa tối ưu, chưa sử dụng các kỹ thuật dùng ajax để gọi API, client-side render… Các bạn có thể tự tạo API rồi dùng ajax gọi nó để giảm tải cho server và nó cũng có thể dễ dàng upscale.

Hi vọng là các bạn thích bài viết của mình. Nếu các bạn thấy bài viết có ích, đừng quên chia sẻ cho bạn bè cùng biết nha. Cảm ơn các bạn.

Theo dõi tin tuyển dụng lập trình viên .NET mới nhất tại đây

Source code trên github

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

Unit Testing phần 2: Phương thức assertion và data provider

Phương thức assertion và data provider

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

Trong phần trước chúng ta đã cài đặt và cấu hình PHPUnit cho một dự án, chúng ta cũng đã tìm hiểu vài quy ước mà PHPUnit yêu cầu, sau đó tạo ra một ví dụ kiểm thử đầu tiên đơn giản và không hữu dụng lắm. Tuy nhiên, có một phương thức assertTrue() được sử dụng trong ví dụ này mà chúng ta chưa hiểu nó làm gì?

  Hướng dẫn viết unit test trong React
  Kiểm thử đơn vị trong C# với Nunit và .Net Core

1. Assertion là gì?

In computer programming, an assertion is a statement that a predicate (Boolean-valued function, a true–false expression) is expected to always be true at that point in the code. If an assertion evaluates to false at run time, an assertion failure results, which typically causes the program to crash, or to throw an assertion exception. Nguồn Wiki

Assertion là một câu lệnh khẳng định cho kết quả true – false, nó được đặt trong chương trình để chỉ cho lập trình viên thấy rằng xác nhận này luôn đúng ở vị trí đặt câu lệnh, hay nói một cách khác assertion kiểm tra một câu lệnh là đúng. Trong ví dụ trước:

public function testTrueIsTrue()
{
    $foo = true;
    $this->assertTrue($foo);
}

Chúng ta xác nhận rằng giá trị fooslàtrue,nếufoosẽlàtrue,nếufoo là false thì kiểm thử cho kết quả là không đạt. PHPUnit có khoảng 90 phương thức assertion, chúng ta không cần phải nhớ tất cả, các assertion có mở đầu là assert: $this->assert*. Một số các assertion hay dùng assertArrayHasKey(), assertEquals(), assertFalse, assertSame() và assertTrue(). Các phương thức assertion chỉ là các phương thức thông thường, nó trả về true hoặc false tùy thuộc vào kết quả các đoạn code mà bạn truyền vào. Nếu bạn không tìm thấy assertion nào phù hợp, bạn có thể tạo ra một assertion. Không có gì quá phức tạp, nó chỉ đơn giản là tạo ra một phương thức trong class kiểm thử. Chúng ta sẽ quay lại vấn đề này trong các bài sau. ## 2. Ví dụ kiểm thử thứ hai

Chúng ta sẽ thực hiện một ví dụ kiểm thử thứ hai hữu ích hơn trong thực tế. Trong tối ưu bộ máy tìm kiếm (SEO) như Google, Bing… các đường dẫn trang web nên sử dụng dấu gạch ngang để phân cách các từ, do vậy cần có một phương thức chuyển từ dòng tiêu đề bài viết sang thành nội dung đường dẫn bằng cách bỏ dấu đi và phân cách bằng dấu gạch ngang. Ví dụ bài viết “Unit Testing với PHPUnit” sẽ được chuyển thành “unit-testing-voi-phpunit”. Chúng ta cùng tạo ra một Class URL trong app để xử lý các vấn đề về URL:

<?php
namespace app;
class URL
{
    public function sluggify($string, $separator = '-', $maxLength = 96)
    {
        $title = iconv('UTF-8', 'ASCII//TRANSLIT', $string);
        $title = preg_replace("%[^-/+|\w ]%", '', $title);
        $title = strtolower(trim(substr($title, 0, $maxLength), '-'));
        $title = preg_replace("/[\/_|+ -]+/", $separator, $title);
        return $title;
    }
}

Sau khi tạo ra được phương thức sluggify() chúng ta muốn kiểm thử xem phương thức này hoạt động có đúng như mong muốn hay không? Có thể có những lỗi tiềm ẩn không lường trước được. Để kiểm thử phương thức chúng ta sẽ tạo ra một file test ./test/URLTest.php với nội dung như sau:

<?php
namespace Test;
class URLTest extends \PHPUnit_Framework_TestCase
{
    //
}

Thử chạy PHPUnit xem đã có phát hiện gì chưa?

Admin@ADMIN-PC c:\xampp\htdocs\phpunit
$ vendor\bin\phpunit
PHPUnit 5.7.21 by Sebastian Bergmann and contributors.

.W                                                                  2 / 2 (100%)

Time: 60 ms, Memory: 2.50MB

There was 1 warning:

1) Warning
No tests found in class "app\Test\URLTest".

WARNINGS!
Tests: 2, Assertions: 1, Warnings: 1.

Như vậy là đã có hai kiểm thử đã được thực hiện, trong đó có 1 xác nhận là kiểm thử thành công và 1 cảnh báo. Nguyên nhân cảnh báo là do PHPUnit không tìm thấy phương thức test nào trong file test\URLTest.php. Tiếp theo chúng ta sẽ đưa vào phương thức test cho URL::sluggify() để xác nhận rằng phương thức này sẽ trả về một kết quả như mong muốn.

<?php
namespace Test;
class URLTest extends \PHPUnit_Framework_TestCase
{
    public function testSluggifyReturnsSluggifiedString()
    {
        // Kiểm tra phương thức sluggify có trả về một chuỗi không dấu và phân cách bằng dấu gạch ngang
    }
}

Khi chạy lại PHPUnit chúng ta đã thấy không còn cảnh báo. Tuy nhiên trong phương thức kiểm thử chúng ta chưa thực hiện gì, tiếp theo sửa đổi nội dung phương thức testSluggifyReturnsSluggifiedString():

<?php
namespace Test;
use app\URL;
class URLTest extends \PHPUnit_Framework_TestCase
{
    public function testSluggifyReturnsSluggifiedString()
    {
        $originalString = 'Đây là chuỗi cần được xử lý dấu và gạch ngang';
        $expectedResult = 'day-la-chuoi-can-duoc-xu-ly-dau-va-gach-ngang';
        $url = new URL();
        $result = $url->sluggify($originalString);
        $this->assertEquals($expectedResult, $result);
    }
}

Phương thức testSluggifyReturnsSluggifiedString() sẽ kiểm tra một chuỗi “Đây là chuỗi cần được xử lý dấu và gạch ngang” xem sau khi qua phương thức URL::sluggify() có ra kết quả như mong đợi là “day-la-chuoi-can-duoc-xu-ly-dau-va-gach-ngang” hay không? Chúng ta chạy PHPUnit:

Admin@ADMIN-PC c:\xampp\htdocs\phpunit
$ vendor\bin\phpunit
PHPUnit 5.7.21 by Sebastian Bergmann and contributors.

..                                                                  2 / 2 (100%)

Time: 63 ms, Memory: 2.25MB

OK (2 tests, 2 assertions)

Như vậy cả hai kiểm thử (ví dụ 1 và ví dụ 2) đều thành công với 2 xác nhận. Trường hợp test ở trên chúng ta mới chỉ kiểm tra các chuỗi chứa ký tự thông thường, trong một kịch bản test đầy đủ, chúng ta có thể test cả các trường hợp khác như chuỗi chứa các ký tự số, ký tự đặc biệt… Điều chỉnh lại code của file test URLTest.php như sau:

<?php
namespace Test;
use App\URL;
class URLTest extends \PHPUnit_Framework_TestCase
{
    public function testSluggifyReturnsSluggifiedString()
    {
        // Phương thức này kiểm thử với một chuỗi thông thường
        $originalString = 'Đây là chuỗi cần được xử lý dấu và gạch ngang';
        $expectedResult = 'day-la-chuoi-can-duoc-xu-ly-dau-va-gach-ngang';
        $url = new URL();
        $result = $url->sluggify($originalString);
        $this->assertEquals($expectedResult, $result);
    }

    public function testSluggifyReturnsExpectedForStringsContainingNumbers()
    {
        // Phương thức này kiểm thử với một chuỗi có chữ số
        $originalString = 'Unit testing phần2 PHPUnit có 100phương thức xác nhận';
        $expectedResult = 'unit-testing-phan2-phpunit-co-100phuong-thuc-xac-nhan';
        $url = new URL();
        $result = $url->sluggify($originalString);
        $this->assertEquals($expectedResult, $result);
    }

    public function testSluggifyReturnsExpectedForStringsContainingSpecialCharacters()
    {
        // Phương thức này kiểm thử với một chuỗi có ký tự đặc biệt
        $originalString = 'Unit testing - Phần 2: Assertion() và dataProvider';
        $expectedResult = 'unit-testing-phan-2-assertion-va-dataprovider';
        $url = new URL();
        $result = $url->sluggify($originalString);
        $this->assertEquals($expectedResult, $result);
    }

    public function testSluggifyReturnsExpectedForEmptyStrings()
    {
        // Kiểm thử với chuỗi đầu vào là rỗng
        $originalString = '';
        $expectedResult = '';
        $url = new URL();
        $result = $url->sluggify($originalString);
        $this->assertEquals($expectedResult, $result);
    }
}

Trong nội dung file test tiếp theo này, chúng ta đã thêm vào các phương thức test mới: – testSluggifyReturnsExpectedForStringsContainingNumbers: để kiểm tra xem URL::sluggify() có hoạt động tốt với một chuỗi có chứa số.

  • testSluggifyReturnsExpectedForStringsContainingSpecialCharacters: kiểm tra xem URL::sluggify() có hoạt động tốt với ký tự đặc biệt không.
  • testSluggifyReturnsExpectedForEmptyStrings: kiểm tra xem URL::sluggify() hoạt động tốt chuỗi đầu vào rỗng không.

Thực hiện chạy test với PHPUnit:

Admin@ADMIN-PC c:\xampp\htdocs\phpunit
$ vendor\bin\phpunit
PHPUnit 5.7.21 by Sebastian Bergmann and contributors.

......                                                              6 / 6 (100%)

Time: 71 ms, Memory: 2.25MB

OK (6 tests, 6 assertions)
``

Như vậy chúng ta thấy có 6 trường hợp kiểm thử được thực hiện và kết quả đều là tốt. Tuy nhiên, chúng thấy có một vấn đề là có quá nhiều phương thức kiểm thử được viết ra, cảm giác như có cái gì đó được lặp đi lặp lại. Nếu như URL::sluggify() có hàng trăm trường hợp cần test mà viết như thế này thì thật là không ổn. PHPUnit cũng đã tính đến trường hợp này, với dataProvider, các phương thức kiểm thử sẽ được cô đọng lại. ## 2. Phương thức cung cấp dữ liệu

 Như ở trong ví dụ trên chúng ta thấy có rất nhiều các phương thức kiểm thử, PHPUnit đã đưa ra phương thức cung cấp dữ liệu (data provider) giúp cho các phương thức kiểm thử này có thể được viết lại rất ngắn gọn. Chúng ta sẽ cùng tìm hiểu các phương thức này, trước khi đi vào tìm hiểu data provider chúng ta tìm hiểu về annotation vì nó được sử dụng để các phương thức kiểm thử nhận biết được phương thức nào sẽ cung cấp dữ liệu cho nó. Annotation là các thẻ được sử dụng trong một khối chú thích giúp tăng thêm thông tin cho mã nguồn. Ngôn ngữ PHP không có core engine cho annotation, các class trong PHPUnit sử dụng annotation để có thêm các thông tin, nó có thể dùng trong lúc chạy để thiết lập các hành vi. Một khối chú thích trong PHP được bắt đầu bằng /\*\* và kết thúc bằng \*/. 

```{.language-php}
/**
 * @annotationName Annotation value
 */
public function testFoo()
{
    //
}

Chúng ta quay lại với phương thức cung cấp dữ liệu data provider, như đã nói ở trên có thể dùng nó để cung cấp dữ liệu kiểm thử cho một phương thức kiểm thử. Nó sử dụng annotation @dataProvider để nhận biết là nó thuộc về phương thức kiểm thử nào. Như vậy chúng ta không cần tạo ra nhiều các phương thức kiểm khác nhau, thay vào đó chúng ta chỉ cần tạo ra một phương thức với tham số là một data provider.

<?php
namespace Test;
use App\URL;

class URLTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @param string $originalString Chuỗi cần xử lý
     * @param string $expectedResult Kết quả mong đợi
     *
     * @dataProvider providerTestSluggifyReturnsSluggifiedString
     */
    public function testSluggifyReturnsSluggifiedString($originalString, $expectedResult)
    {
        $url = new URL();
        $result = $url->sluggify($originalString);
        $this->assertEquals($expectedResult, $result);
    }

    public function providerTestSluggifyReturnsSluggifiedString()
    {
        return array(
            array('Đây là chuỗi cần được xử lý dấu và gạch ngang', 'day-la-chuoi-can-duoc-xu-ly-dau-va-gach-ngang'),
            array('ĐÂY LÀ CHUỖI CẦN XỬ LÝ DẤU VÀ GẠCH NGANG', 'day-la-chuoi-can-duoc-xu-ly-dau-va-gach-ngang'),
            array('Unit testing phần2 PHPUnit có 100phương thức xác nhận', 'unit-testing-phan2-phpunit-co-100phuong-thuc-xac-nhan'),
            array('Unit testing - "Phần 2": Assertion() và dataProvider!', 'unit-testing-phan-2-assertion-va-dataprovider'),
            array('', ''),
        );
    }
}

Bạn thấy đấy, thay vì rất nhiều các phương thức kiểm thử, chúng ta đã có một phương thức kiểm thử duy nhất và một phương thức cung cấp dữ liệu để kiểm thử và được mapping thông qua annation @dataProvider. Kết quả khi thực hiện kiểm thử với PHPUnit:

Admin@ADMIN-PC c:\xampp\htdocs\phpunit
$ vendor\bin\phpunit
PHPUnit 5.7.21 by Sebastian Bergmann and contributors.

.......                                                             7 / 7 (100%)

Time: 79 ms, Memory: 2.50MB

OK (7 tests, 7 assertions)

Như vậy, thay thì phải viết 6 phương thức kiểm thử chúng ta sử dụng Data Provider giúp cho code được gọn gàng hơn. ## 3. Kết luận

Phần 2 đã kết thúc với những kiến thức giúp bạn có thể viết các chương trình kiểm thử ngắn gọn nhưng rất đầy đủ các trường hợp cần test. Chúng ta đã đi qua các vấn đề cơ bản nhất của Unit testing trong PHP, trong phần tiếp theo chúng ta sẽ đi sâu hơn vào cách kiểm thử các thành phần của một class với các phạm vi truy cập thành phần khác nhau, cuối cùng chúng ta sẽ cùng tìm hiểu cách thức sinh ra các báo cáo kiểm thử (test report) giúp công tác quản lý tốt hơn.

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

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

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

Hướng dẫn kiểm tra performace với Chrome DevTools

Hướng dẫn kiểm tra performace với Chrome DevTools

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

Bước 1: Cài đặt DevTools

Giả sử bạn nhận được phàn nàn từ user là trang nào đó trên site load quá chậm. Bạn cần check theo các bước

  1. Mở trang này trong cửa sổ private mới
  2. Ấn tổ hợp phím Ctrl + Shift + I để mở DevTools
  3. Click tab Network

Hướng dẫn kiểm tra performace với Chrome DevTools

  1. Click nút Capture Screenshots , nó chuyển sang xanh, để capture screenshot trong suốt quá trình trang được load

Bước 2: Giả lập mobile

Sử dụng web trên máy tính thì ít có vấn đề, vì tốc độ mạng ngày nay được cải thiện nhiều, nếu máy tính mà vẫn chậm thì bạn xem lại nhé, giả lập xem trải nghiệm trên mobile thế nào

  30 tiện ích Chrome cho designer và dev
  Cách build một extension (tiện ích mở rộng) trên Chrome
  1. Check vào ô Disable Cache để quá trình kiểm tra chính xác hơn
  2. Từ dropdown menu đang có giá trị No throttling chọn xuống Regular 2G. DevTools sẽ giả lập tốc độ mạng xuống 2G

Hướng dẫn kiểm tra performace với Chrome DevTools

Bước 3: Đánh giá kết quả

Tìm xem đâu là nguyên nhân làm chậm page load bằng cách reload lại trang và xem xét kết quả.

Tìm các đoạn script block render

Khi trình duyệt gặp tag <script>, nó sau pause việc render, thực thi đoạn script ngay lập tức. 1. Tìm các đoạn script không thật sự cần chạy ngay lập tức, đánh dấu async hoặc defer Ấn tổ hợp Ctrl + R để load lại trang.

Hướng dẫn kiểm tra performace với Chrome DevTools

  1. Để ý giá trị của DOMContentLoaded trong tab Summary, phía dưới tab Network. Bạn sẽ thấy 4 giây.
  2. Click file main.js để xem, nó mở ra một tab mới show chi tiết hơn
  3. Click vào tab Preview để xem source code. Đoạn script này đợi 4000ms, đánh dấu nó là async và chuyển xuống dưới <body>

Hướng dẫn kiểm tra performace với Chrome DevTools

Đọc thêm Parser-blocking vs. async Javascript để tìm hiểu thêm về script block render

Tìm các request lớn

Trong source ví dụ, bạn thấy cái logo sẽ load rất chậm, mặc dù nó không hề block render

  1. Mở lại tab Network
  2. Double click lên hình screenshot
  3. Click mũi tên để di chuyển qua lại giữa các screenshot. Bên dưới screenshot là thời gian nó được chụp
  4. Hover lên Waterfall cho request logo-1024.png. Phần lớn thời gian tiêu tốn cho việc download hình này.

Hướng dẫn kiểm tra performace với Chrome DevTools

Xác nhận lại các thay đổi đã fix

Chúng ta đã thực hiện 2 thay đổi

  • Chuyển <script> xuống dưới body, đánh dấu thành async
  • Đổi logo sang SVG

Giờ chúng ta chạy test lại một lần nữa để xem nó cải thiện được phần nào chưa

  1. Mở trang đã sữa trên tab private mới
  2. Setup DevTools tương tự như lúc trước
  3. Reload lại trang

Hướng dẫn kiểm tra performace với Chrome DevTools

Đọc thêm

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

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

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

5 bước đơn giản để bắt đầu học Java cơ bản

java cơ bản
5 bước đơn giản để bắt đầu học Java cơ bản

Tác giả: Code Hump

Ngôn ngữ lập trình Java là gì?

Java là một một ngôn ngữ lập trình hiện đại, bậc cao, hướng đối tượng, bảo mật và mạnh mẽ. Java cũng được biết đến là platform hiệu quả để chạy các phần mềm. Với những tính năng ưu việt và nổi bật của mình, nhiều dev xem việc tìm hiểu Java cơ bản là cần thiết để nâng cao tay nghề và kỹ năng làm việc của mình.

5 bước để bắt đầu học Java cơ bản

1. Đừng chần chừ khi bắt đầu

Không chỉ riêng với việc bắt đầu học Java cơ bản mà với bất cứ ngôn ngữ lập trình nào, bất cứ lĩnh vực nào đi chăng nữa, bạn cũng nên bắt đầu ngay lập tức. Đừng chờ đợi vào ngày mai hay một lúc nào khác cả. Lúc tốt nhất để bắt đầu là ngay bây giờ.

Theo thống kê, có từ 80% – 90% sinh viên khi bắt đầu học lập trình luôn do dự và chần chừ. Khi bạn dừng lại cũng là lúc người khác bắt đầu, trì hoãn sẽ khiến bạn chậm bước hơn người khác mà thôi.

học java cơ bản
Java cơ bản là kiến thức giúp ích cho quá trình làm việc của các dev

2. Hãy tìm ra phương pháp học tập thích hợp nhất với bạn

Để học Java cơ bản hiệu quả bạn cần tìm ra phương pháp học cũng như thực hành phù hợp với mình. Nhất là với những bạn lần đầu làm quen với Java thì nên sớm tìm ra cách học hiệu quả để đảm bảo có thể hiểu được ngọn nguồn của Java cũng như cách áp dụng nó vào thực tiễn làm việc.

Tìm Java job lương cao trên TopDev ngay!

Bạn có thể tìm hiểu về ngôn ngữ lập trình Java trên sách vở hoặc các bài giảng của thầy cô nếu còn là sinh viên. Bên cạnh đó, nhiều dev hiện nay lựa chọn học Java online vì sự tiện lợi mà nó mang lại. Có hàng tá các trang web, kênh video phục vụ học lập trình online. Không mất thời gian đến lớp cũng như linh hoạt được thời gian, học trực tuyến trở thành giải pháp hợp lí cho những người bận rộn và muốn học thêm các kiến thức bên ngoài.

Nhưng quan trọng nhất vẫn là sự chủ động của người học. Để đạt được kết quả tốt nhất khi học Java cơ bản, bạn nên thường xuyên thực hành các bài tập và áp dụng những kiến thức mình đã được học vào công việc. Như thế, bạn sẽ không chỉ nhớ nhanh mà còn nhớ sâu được các kiến thức liên quan Java cơ bản. Từ đó dễ dàng trong việc học các ngôn ngữ lập trình nâng cao hơn.

Xem thêm 10 lý do cho thấy tại sao bạn nên theo học ngôn ngữ lập trình Java

3. Dành thời gian học Java cơ bản mỗi ngày

Luyện tập chính là chìa khóa của việc tiếp thu và áp dụng kiến thức tốt, nhất là với ngành IT. Mỗi ngày có rất nhiều các data mới, kiến thức mới và những sự thay đổi trong lĩnh vực này mà bạn cần tiếp nhận. Mỗi ngày bạn nên dành ra ít nhất 30 – 45 phút để học thêm các kiến thức Java mới.

Trong khoảng thời gian đó, bạn có thể nghiên cứu thêm các thông tin liên quan đến Java từ Java cơ bản đến nâng cao. Nếu gặp phải những vấn đề khó khăn mà không thể tự giải thích được, bạn có thể tham khảo thêm ý kiến và lời khuyên từ các dev đi trước. Những kinh nghiệm thực tế mà họ đã trải qua chắc chắn sẽ giúp ích cho bạn rất nhiều đó.

học java online
Sự tập trung và kiên định giúp bạn học java hiệu quả hơn

4. Giữ sự thoải mái khi học tập

Sự gò bó và khó chịu khi học tập và làm việc sẽ khiến bạn cảm thấy mệt mỏi và không thể tiếp thu kiến thức hiệu quả được. Vậy nên hãy cố gắng giữ sự thoải mái và vui vẻ khi học Java cơ bản, bạn sẽ làm quen với các kiến thức lý thuyết và xử lý các bài tập tình huống tốt hơn.

  5 điều lập trình viên Java Developer chắc chắn sẽ thích ở Kotlin
  11 mẹo đơn giản để tăng hiệu suất Java cấp tốc

5. Kiên định với quá trình học ngôn ngữ lập trình Java

Điều kiện tiên quyết để thành công khi học Java cơ bản, kể cả học Java online đó là bạn cần lên kế hoạch để đi đúng hướng và giữ sự tập trung trong việc học hành. Trước khi bắt đầu, bạn nên lên kế hoạch rõ ràng và sắp xếp thời gian biểu hợp lý để tránh việc xao nhãng hay phải dừng việc học lại để làm việc khác. Gián đoạn giữa chừng sẽ khiến bạn không nhớ kiến thức và mất tập trung khi làm việc.

Kết luận

Java được sử dụng trong các lĩnh vực khác nhau từ Desktop app như Acrobat Reader, Media Player, Antivirus,… Web app như irctc.co.in, javatpoint.com,… hay Enterprise app. Do đó việc học Java sẽ giúp bạn hoạt động tốt hơn trong lĩnh vực lập trình. Đó cũng sẽ là cơ hội để bạn tìm được công việc ở những công ty tốt và chuyên nghiệp như Gear Inc.

Bài viết được transcript dựa trên video gốc tại đây

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

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

Mẫu CV Junior Developer cực thu hút cho dân IT

CV Junior Developer
CV Junior Developer

Lập trình viên sẽ viết CV Junior Developer như thế nảo? Có những điều gì thú vị xoay quanh CV IT? Ứng viên IT cần làm gì để CV của mình ăn điểm với nhà tuyển dụng. Cùng TopDev theo dõi bài viết sau đây để biết cách viết CV Junior Developer cực chuẩn.

Thông tin cá nhân của bạn

Hãy cung cấp các thông tin về: 

  • Số điện thoại 
  • Email
  • Kênh liên hệ cá nhân (nếu có)

Ngoài ra, bạn có thể dẫn một số link tài khoản networking cá nhân để gia tăng mức độ chuyên nghiệp như LinkedIn, Skype,… Một điều đặc biệt nữa là hãy chọn một bức hình thật phù hợp trong CV Junior Developer của mình. 

Mục tiêu phát triển nghề nghiệp

Mục này, bạn cần chia sẻ nhựng mục tiêu phát triển rõ ràng, đúng trọng tâm, tránh lan man. 

  Cách viết CV giúp lập trình viên ghi điểm với nhà tuyển dụng
  5 mẹo và mẫu CV IT để gây ấn tượng với nhà tuyển dụng!

Ví dụ: Tôi apply với mục đích: Học tập, trải nghiệm với một mọi trường làm việc chuyên nghiệp hơn. Tôi muốn làm việc tại … với vị trí Junior Developer và mục tiêu ngắn hạn/dại hạn của tôi là… trở thành….

Đồng thời, viết CV giúp bạn định hình và có những trải nghiệm tốt hơn. Trường hợp bạn ứng tuyển các vị trí khác như freelancer it hay Senior Developer đều sẽ đạt hiệu quả ứng tuyển cao hơn.

Là một Junior, kinh nghiệm của bạn chưa nhiều. Nhưng nếu được hãy khéo léo đưa thêm một số mô tả về các điểm nổi trội của bạn.

+ Những trải nghiệm việc làm (Junior chưa cần đề cập số năm kinh nghiệm)

+ Chứng chỉ chuyên ngành mà bạn đã đạt được trong quá trình học tập 

+ Các kỹ năng liên qua trực tiếp đến vị trí Junior Developer

Nền tảng chuyên môn (Kiến thức)

Trình bày trường học hoặc các khóa học bạn được trải nghiệm. Một mẹo là bạn hãy đề cập các khóa học chuyên môn có liên quan vị trí Junior. Có thể là ứng viên mới nên CV cho sinh viên IT mới ra trường của bạn chưa thật sự hoàn hảo. 

Bên cạnh đó việc nắm bắt các cách viết CV, kỹ năng viết đơn xin nghỉ việc, đơn xin nghỉ phép, kỹ năng giao tiếp, cũng đều là khía cạnh cần được quan tâm.

Tuy nhiên, đặt trong trường hợp ứng tuyển nhiều vị trí khác nhau từ Junior, Senior Developer, Mobile App Developer thì CV IT ít nhất phải đảm bảo được những tiêu chuẩn nhất định.

Kinh nghiệm làm việc

Trình bày những trải nghiệm mà bạn có trên hành trình trở thành Junior Dveloper. Có thể là những dự án nhỏ, các chương trình tiếp cận khoa học chuyên nghiệp. Hoặc cũng có thể là thời gian bạn làm thực tập sinh (ghi cụ thể thời gian). Kinh nghiệm freelancer IT cũng được xem là một kinh nghiệm khá quan trọng cho CV lập trình của bạn.

Xem thêm các vị tri tuyển dụng IT nổi bật

Bạn ghi rõ nhiệm vụ nhưng cần đảm bảo không quá dài dòng. Thông qua từng trải nghiệm công việc, nhà tuyển dụng sẽ hiểu rõ hơn về sự định hướng sự nghiệp sắp tới của bạn. 

Tạo CV IT chuẩn ATS miễn phí trên TopDev

Những kỹ năng của bạn

Liệt kê các kỹ năng bạn có đồng thành thể hiện cột phản ánh mức độ tương ứng năng lực thật sự của bạn. Cùng TopDev checklist các kỹ năng cần có trong hành trình trở thành một IT Junior chính hiệu nhé. Quan trọng hơn, bạn cần phải lưu tâm về việc các kỹ năng phải thể hiện đúng năng lực mà bạn sở hữu.

+ Kỹ năng giao tiếp

+ Kỹ năng tư duy hệ thống/quản lý

+ Teamwork 

+ Tin học văn phòng

+ Ngoại ngữ

Các chứng chỉ giải thưởng – hoạt động ngoại khóa/sở thích

Những nội dung này không bắt buộc có trong CV Junior Developer. Một phần vì độ nhận diện không quá phổ biến. Và hầu như các nhà tuyển dụng cũng ít quan tâm đến các phần nội dung này. Các ứng viên cho vị trí Junior Dveloper cần linh động trong việc lựa chọn các nội dung phù hợp trong CV của mình.

Các mẫu CV Junior Developer trên TopDev

Bạn có thể tham khảo nội dung để hoàn thiện CV IT của mình.

cv junior front end developer
Mẫu CV cổ điển
junior backend developer cv
Mẫu CV cổ điển
junior backend developer cv
M1 – CV đa nhiệm
CV Junior Developer
M2 – CV đa nhiệm
cv for junior developer
M3 – CV đa nhiệm
cv for junior developer
M1 – CV Pro
CV Junior Developer
M2 – CV Pro

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

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

Vài vấn đề thường gặp khi làm việc với Flexbox

Vài vấn đề thường gặp khi làm việc với Flexbox

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

Khi làm về UI, giải pháp nào cho khoảng cách đều nhau giữa các phần tử, cũng như là các phần tử luôn cao bằng nhau dù content thay đổi ?

Vấn đề 1: Để các cột cao bằng nhau thì trong Flexbox khi dùng display: flex thì giá trị mặc định flex-direction: row và align-items: stretch, giá trị stretch làm các phần tử con trực tiếp của thẻ cha dùng display: flex luôn cao bằng nhau. Lưu ý là theo flex-direction: row và flex-wrap: nowrap, nếu dùng wrap thì một phần tử rớt xuống tạo thành hàng mới và nó sẽ so sánh với các phần tử cùng hàng với nó mà thôi, dù nó cao thế nào thì cũng không ảnh hưởng tới chiều cao của các phần tử hàng khác.

  Cách vận hành của Flexbox
  Làm layout masonry bằng flexbox

Vấn đề 2: Khi chia layout với chỉ 3 phần tử như hình thì dùng justify-content: space-between sau đó xác định khoảng cách giữa mỗi phần tử, ở đây ta có 30px, chúng ta có 3 cột từ đó khoảng cách ở giữa sẽ là 30×2 = 60px sau đó chia cho 3 cột = 20px. Từ đó ta có thể CSS độ rộng của các phần tử là width: calc(33.333% - 20px) kết quả ra sẽ chính xác như Design (đã test) ở bài PSD phần 5.

Vấn đề 3: Cũng layout như trên nhưng chỉ có 5 phần tử, khi dùng space-between, có flex-wrap: wrap thì phần tử số 4 và 5 sẽ xuống hàng, tuy nhiên phần tử số 5 sẽ nằm về cuối làm xấu layout. Giải pháp là để giá trị justify-content về mặc định là flex-start, tuy nhiên các phần tử sẽ dính nhau.

Từ đây ta có giải pháp khác đó là chúng ta đã biết khoảng cách giữa các phần tử là 30px, suy ra mỗi bên của phần tử sẽ chiếm 15px khoảng trống, ta có thể dùng margin: 0 15px cho các phần tử đó, kết hợp với width: calc(33.333% - 30px), -30px vì khi dùng margin hai bên 15px nó đẩy ra. Nhưng phần tử đầu và cuối như số 1 và 3 sẽ bị bóp vào do margin-left cũng như margin-right, từ đây ta CSS cho class cha margin số âm là margin: 0 -15px để đẩy ra lại, cái này khá quen nếu các bạn dùng Bootstrap3 trong các class như col-md-x hay dùng cái này.

Trên đây là vài tips tricks của bản thân mình hi vọng sẽ giúp ích cho các bạn. Chúc các bạn học tập tốt, nâng cao trình độ.

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

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

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

Unit Testing phần 1 – Giới thiệu PHPUnit

Giới thiệu PHPUnit

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

1. Kiểm thử ứng dụng là gì?

Kiểm thử phần mềm là một khâu quan trọng trong phát triển phần mềm, trước đây chúng ta thường xem nhẹ việc này vì mấy lý do: thích làm tùy tiện cho nhanh, thực hiện tốn kém hơn… Những sản phẩm được gọt dũa cẩn thận mang lại trải nghiệm tốt cho người dùng và cũng vì thế nó tồn tại lâu hơn, thành công hơn. Kiểm thử phần mềm được chia thành nhiều dạng khác nhau theo phạm vi và giai đoạn triển khai, chúng ta cùng xem một số dạng kiểm thử chính:

  • Unit testing: Kiểm thử ở mức đơn vị mã nguồn. Một đơn vị mã nguồn là thành phần nhỏ nhất trong mã nguồn mà chúng ta có thể kiểm tra. Như vậy, trong Unit testing chúng ta sẽ kiểm thử các lớp (class), phương thức (method)… Mục tiêu của unit testing là kiểm tra tính đúng đắn trong các xử lý của từng đơn vị mã nguồn.
  • Integration testing: Kiểm thử tích hợp các thành phần một ứng dụng, được thực hiện sau Unit test. Trong Integration testing chúng ta có thể kiểm tra cấu trúc ứng dụng, kiểm tra chức năng, hiệu năng sản phẩm cũng như khả năng chịu tải ứng dụng.
  • Ngoài ra còn rất nhiều các dạng kiểm thử khác như Acceptance testing, kiểm tra xem ứng dụng đã đạt được yêu cầu khách hàng chưa, security testing – kiểm tra tính bảo mật của ứng dụng…
  Hướng dẫn viết unit test trong React
  Kiểm thử đơn vị trong C# với Nunit và .Net Core

Trong loạt bài viết này, chúng ta sẽ chỉ tập trung vào Unit testing khi thực hiện một dự án bằng ngôn ngữ PHP.

Giới thiệu PHPUnit

2. Unit testing với PHPUnit

PHPUnit là một gói thư viện mã nguồn mở sử dụng trong Unit testing với ngôn ngữ PHP rất tốt, nó cung cấp rất nhiều các class, phương thức giúp cho việc viết các đoạn mã kiểm thử trở nên nhanh chóng và thuận lợi. Chúng ta sẽ cùng nhau khám phá PHPUnit để thấy được sức mạnh của nó trong việc kiểm thử ứng dụng PHP.

2.1 Cài đặt PHPUnit

Đầu tiên, để sử dụng được PHPUnit chúng ta cần cài đặt nó vào dự án. Trong loạt bài viết này, chúng ta sẽ tạo ra một dự án tên phpunit nằm trong C:/xampp/htdocs (do tôi dùng XAMPP). PHPUnit được cài đặt thông qua composer:

Admin@ADMIN-PC c:\xampp\htdocs\phpunit
$ composer require phpunit/phpunit
Using version ^5.7 for phpunit/phpunit
./composer.json has been updated
Loading composer repositories with package information
...
phpunit/phpunit suggests installing phpunit/php-invoker (~1.1)
phpunit/phpunit suggests installing ext-xdebug (*)
Writing lock file
Generating autoload files

Cài đặt PHPUnit như vậy đã xong, chúng ta cùng xem cấu trúc thư mục dự án PHPUnit:

Giới thiệu PHPUnit

Các thư mục và file trong thư mục phpunit như sau:

  • app: Chứa code ứng dụng.
  • test: Chứa code cho kiểm thử ứng dụng.
  • vendor: được tạo ra bởi composer, chứa mã nguồn của gói thư viện PHPUnit.
  • composer.json: thiết lập các gói thư viện trong ứng dụng với composer.
  • phpunit.xml là file cấu hình cho PHPUnit.

Mặc định file phpunit.xml chưa có, bạn có thể tạo ra với nội dung như sau:

<?xml version="1.0" encoding="UTF-8"?>
<phpunit colors="true">
    <testsuites>
        <testsuite name="Application Test Suite">
            <directory>./test/</directory>
        </testsuite>
    </testsuites>
</phpunit>

Giải thích qua một số thiết lập trong phpunit.xml:

  • colors=”true” thiết lập để PHPUnit hiển thị màu trong kết quả test.
  • ./test/

Ứng tuyển ngay các vị trí PHP tuyển dụng mới nhất trên TopDev

2.2 Các quy ước trong PHPUnit

2.2.1 Cấu trúc thư mục và tên file

PHPUnit có một số quy ước để quá trình test thuận lợi. Quy ước đầu tiên là về cấu trúc file và tên file. Các file test cần được ánh xạ 1-1 với codebase và tên file được thêm chữ Test. Ví dụ:

./app/Foo.php
./app/Bar.php
./app/Controller/Baz.php

Cấu trúc thư mục Test sẽ như sau:

./test/FooTest.php
./test/BarTest.php
./test/Controller/BazTest.php

2.2.2 Class và phương thức

Tên class là giống với tên file và phải mở rộng class PHPUnit_Framework_TestCase. Phương thức kiểm thử cần được đặt tên với bắt đầu bằng test, tên phương thức phải mô tả được hành động test. Ví dụ, nếu bạn test một phương thức verifyAccount(), bạn có thể đặt tên phương thức kiểm thử là testVerifyAccountMatchesPasswordGiven(). Các phương thức test phải là public, PHPUnit không thể chạy các test với các phương thức protected hoặc private. ## 3. Ví dụ kiểm thử đầu tiên

Chúng ta thực hiện ví dụ kiểm thử đầu tiên, trong ví dụ này việc test chỉ đơn giản là kiểm tra xem một biến có giá trị là true hay không? Tạo ra file FirstTest.php trong thư mục test với nội dung:

<?php
namespace Test;
class FirstTest extends \PHPUnit_Framework_TestCase
{
    public function testTrueIsTrue()
    {
        $foo = true;
        $this->assertTrue($foo);
    }
}

không có gì đặc biệt, chỉ đơn giản là tạo ra một Class mở rộng PHPUnit_Framework_TestCase. Tiếp theo chúng ta sẽ tạo ra một phương thức để kiểm tra xem biến $foo có giá trị true hay không? OK, giờ là lúc chạy PHPUnit từ màn hình dòng lệnh để thực hiện kiểm thử:

Admin@ADMIN-PC c:\xampp\htdocs\phpunit
$ vendor\bin\phpunit
PHPUnit 5.7.21 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 53 ms, Memory: 2.25MB

OK (1 test, 1 assertion)

PHPUnit đã thông báo là có 1 kiểm thử được thực hiện và kết quả là kiểm thử này có kết quả tốt. Ví dụ đầu tiên này có vẻ quá đơn giản, nhưng cũng nhờ đó chúng ta kiểm tra các thiết lập ban đầu cho PHPUnit và cũng là để chúng ta thấy việc kiểm thử không phải là một cái gì đó phức tạp.

4. Lời kết

Trong bài đầu tiên này, bạn đã hiểu sơ lược về Unit testing và cách sử dụng gói thư viện PHPUnit với ví dụ khá đơn giản. Việc kiểm thử ứng dụng là phải tìm ra nhiều các trường hợp thử nghiệm khác nhau để tránh bị bỏ sót lỗi, chính vì thế các đoạn mã kiểm thử cũng phải vét cạn được các trường hợp kiểm thử. Phần tiếp theo chúng ta sẽ đi sâu hơn về Assertsion và Anotation, những ý tưởng này giúp cho việc kiểm thử gọn gàng hơn.

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

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

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

Entity-relationship Model

Entity-relationship Model

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

Entity-relationship Model là gì?

Entity-relationship model (tạm dịch là mô hình thực thể – mối quan hệ hay mô hình quan hệ – thực thể, viết tắt là ER model) là mô hình biểu diễn mối quan hệ giữa các thực thể với nhau. Trong thực tế thì hầu như mọi thực thể đều có mối quan hệ với nhau.

Ví dụ như một người sở hữu một hoặc nhiều căn nhà, khi đó, người này và căn nhà là vật thể, quan hệ giữa người và nhà là quan hệ sở hữu và được sở hữu bởi.

  Các mô hình phát triển phần mềm
  Giải thích mô hình MVC thông qua … cốc trà đá

Bằng việc sử dụng mô hình ER, chúng ta có thể dễ dàng đặc tả được mối quan hệ giữa các thực thể ngoài đời thực, từ đó thiết kế các cơ sở dữ liệu quan hệ phù hợp để lưu trữ trên máy tính. Bạn nào không biết cơ sở dữ liệu là gì có thể xem lại bài viết này của mình nha.

Các thành phần của mô hình ER

Như đã đề cặp ở trên, đương nhiên hai thành phần phải có là thực thể và mối quan hệ rồi. Ngoài ra còn có thuộc tính của thực thể.

Thực thể

Thực thể (Entity) đơn giản là các đối tượng, sự vật, đồ vật. Nhiều thực thể thì được gọi là một tập thực thể. Trong mô hình ER có thể có nhiều thực thể khác nhau, được ký hiệu bằng hình chữ nhật và tên thực thể bên trong (xem hình kế tiếp trong mục Thuộc tính, nhân viên là thực thể). Ví dụ thực thể (Nhà cửa, xe cộ, phòng ban, nhân viên, sinh viên…).

Ngoài ra còn có 1 loại là thực thể yếu. Thực thể yếu là thực thể thêm vào để bổ sung thông tin cho thực thể chính trong quan hệ và nó không quan trọng. Thông thường khi thiết kế ER model, bạn sẽ hiếm khi thấy thực thể yếu xuất hiện trong mô hình.

Thuộc tính

Thực thể sẽ có các thuộc tính liên quan đến nó. Ví dụ như con người thì sẽ có họ tên, ngày sinh, giới tính, địa chỉ, số CMND… Sinh viên thì có thêm MSSV, trường, lớp…

Thuộc tính trong mô hình ER được ký hiệu là hình bầu dục hoặc tròn cùng với tên thuộc tính bên trong. Thuộc tính thuộc thực thể nào thì sẽ được nối đến thực thể đó.

Thuộc tính dùng để phân biệt giữa các thực thể với nhau gọi là thuộc tính khóa. Thuộc tính khóa ký hiệu tương tự thuộc tính thường nhưng có thêm gạch chân dưới tên thuộc tính.

Entity-relationship Model là gì?
Thực thể và thuộc tính

Giá trị của thuộc tính có 2 loại là đơn trị và đa trị. Đơn trị là các thuộc tính như tên, ngày sinh, giới tính… Đa trị là các thuộc tính như certificates, studied school (có thể có nhiều hơn 1).

Kiểu dữ liệu của thuộc tính đơn trị có thể là string, float, integer, datetime… Các thuộc tính đa trị có thể coi như 1 danh sách các giá trị thuộc các kiểu vừa nêu. Ví dụ ngày sinh kiểu datetime, tên kiểu string, điểm trung bình kiểu float…

Mối quan hệ

Như cái tên của mô hình này, thành phần “mối quan hệ” này thể hiện quan hệ giữa các thực thể trong mô hình và cũng là thành phần cực kỳ quan trọng. Quan hệ này được ký hiệu bằng hình thoi, bên trong là tên mối quan hệ và nó sẽ nối đến các thực thể có quan hệ với nhau.

Mối quan hệ giữa các thực thể có các kiểu sau:

  • Quan hệ 1 – 1: ví dụ như chức trưởng phòng chỉ có thể thuộc về 1 người và cũng chỉ có 1 người có thể giữ chức trưởng phòng trong cùng 1 thời điểm.
  • Quan hệ 1 – n (hoặc n – 1): ví dụ như mỗi chiếc xe hơi được đứng tên bởi 1 người nhưng 1 người có thể có nhiều chiếc xe hơi.
  • Quan hệ n – n: ví dụ như trên đại học, mỗi sinh viên sẽ được tham gia vào các lớp thuộc các môn học khác nhau và mỗi lớp cũng có nhiều sinh viên khác nhau tham gia.

Mối quan hệ giữa thực thể còn được đánh bảng số để biểu thị số chiều của mối quan hệ. Bảng số có dạng sau (min, max), trong đó min là số lượng thực thể tối thiểu tham gia mối quan hệ và max là số thực thể tối đa trong mối quan hệ đó.

Ví dụ như mỗi phòng ban có thể có 1 hoặc nhiều nhân viên (ít nhất 1 và nhiều nhất n nhân viên), mỗi nhân viên thì chỉ có thể thuộc về 1 và chỉ 1 phòng ban (ít nhất 1 và nhiều nhất 1). Ta sẽ thể hiện như sau:

Entity-relationship Model là gì?
Mối quan hệ giữa thực thể Nhân viên và Phòng ban

Tất nhiên đó chỉ là một ví dụ nhỏ thôi, trong thực tế thì một diagram sẽ cực kỳ cực kỳ phức tạp và để tạo nên diagram đó cũng là điều không dễ dàng gì.

Ngoài ra, một thực thể có thể có mối quan hệ với chính nó, ví dụ mỗi nhân viên trong một phòng ban có thể chịu sự quản lý trực tiếp từ một nhân viên khác. Lúc này thì một nhân viên có thể là quản lý hoặc cũng có thể là người bị quản lý. Ta sẽ có như sau:

Entity-relationship Model là gì?

Trong diagram trên, nhân viên có thể không quản lý nhân viên nào (không phải quản lý) và cũng có thể quản lý nhiều nhân viên (là người quản lý). Và một nhân viên cũng có thể được quản lý bởi một nhân viên khác hoặc không bị quản lý (không có quản lý hoặc nhân viên đó là quản lý).

Bonus: mối quan hệ mở rộng – nó cũng là một mối quan hệ nhưng trong mối quan hệ đó có các thông tin (thuộc tính) bổ sung cho nó. Ví dụ như khi phân công đề án cho nhân viên, mối quan hệ ở đây là phân công và được phân công, thì trong đó có thể bổ sung thêm thông tin về số giờ làm việc / tuần được phân công trong đề án đó.

Quy tắc và cách xây dựng ER Model

Có một số quy tắc bạn cần nhớ khi xây dựng ER Model như sau:

  • Mỗi thành phần phải có ý nghĩa trong model
  • Xác định đúng thực thể
  • Có đầy đủ các thuộc tính của thực thể
  • Xác định đúng các mối quan hệ giữa thực thể
  • Model phải đơn giản nhưng đầy đủ thông tin và dễ đọc hiểu

Để xây dựng ER Model, ta thực hiện theo các bước sau:

  1. Xác định tập thực thể
  2. Xác định thuộc tính của thực thể
  3. Xác định kiểu của các thuộc tính
  4. Xác định thuộc tính khóa của các thực thể
  5. Xác định mối quan hệ giữa thực thể
  6. Vẽ ER Model
  7. Chuẩn hóa model

Thực chiến

Từ đầu bài đến giờ toàn nói suôn, giờ thì mình sẽ có một ví dụ thực tế cho các bạn xem để dễ hiểu bài viết hơn. Bài của mình như sau:

Công ty gồm nhiều nhân viên, mỗi nhân viên được gán mã nhân viên để tiện việc quản lý, có họ tên, ngày sinh, mức lương được hưởng. Công ty gồm nhiều phòng ban, mỗi phòng ban có chức năng riêng của mình, có mã phòng, tên phòng, có một trưởng phòng. Mỗi nhân viên chỉ thuộc vào một phòng ban và một phòng có thể có nhiều nhân viên. Mỗi nhân viên trong phòng còn có thể chịu sự quản lý trực tiếp từ một nhân viên khác.

Do công ty thực hiện đề án, nên mỗi phòng có thể có nhiều văn phòng giao dịch hay làm việc khác nhau ở tại những địa điểm khác nhau. Mỗi một đề án khi được xây dựng, có mã đề án, tên đề án, địa điểm thực hiện đề án đó và do một phòng ban chịu trách nhiệm chủ trì đề án.

Quá trình thực hiện đề án có thể được chia nhỏ thành nhiều công việc và phân côn cho các nhân viên thực hiện, khi đó công ty sẽ ghi nhận lại thời gian phân công công việc cho nhân viên (tính bằng số giờ / tuần) để theo dõi tiến độ thực hiện. Nhằm có thể chăm lo đời sống của nhân viên, công ty có ghi nhận lại những thông tin về những thân nhân của nhân viên, bao gồm những người như cha mẹ, chồng vợ, và con cái.

Như vậy từ những thông tin đặc tả vấn đề trong đề bài, mình sẽ vẽ được Entity-relationship model sau:

Bên trên cũng là bài tập của mình nên có thể có sai sót, nếu có sai sót gì mọi người cứ comment bên dưới để mình sửa nha.

Lời kết

Bài viết đến đây khá là dài rồi, mình hi vọng là mọi người có thể hiểu được Entity-relationship model. Trong các bài viết sắp tới, mình sẽ trình bày cách chuyển sang mô hình dữ liệu quan hệ sau, mình sẽ sớm có chuỗi bài viết về mô hình dữ liệu quan hệ và SQL thôi, các bạn hãy nhấn đăng ký nhận thông báo nhé!

Nếu các bạn có bất kỳ thắc mắc hay góp ý nào đừng ngần ngại comment phía bên dưới bài viết để giúp mình phát triển bài viết tốt hơn nha. Đừng quên chia sẻ bài viết nếu mọi người thấy nó hay cũng như để ủng hộ tinh thần cho mình. Cảm ơn các bạn đã đọc bài viết!

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

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

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

Những cách thay đổi giá trị fill của SVG khi hover

Những cách thay đổi giá trị fill của SVG khi hover

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

File SVG

<svg class="icon">
  <path />
</svg>

Thay đổi bằng giá trị fill

Cách dễ nhất, 1 dòng css duy nhất

.icon:hover {
    fill: #DA4567;
}

Tuy nhiên cái này chỉ làm được khi chúng ta sử dụng file svg dạng inline, nếu dùng thẻ <img src='duong-dan-file.svg''/>, để tách riêng file svg ra cho nó sạch sẽ file html, cached lại hình này trên trình duyệt, thì coi như chúng ta không thực hiện được cách ở trên.

  11 công cụ hữu ích để kiểm tra và tối ưu hóa các file CSS
  Hoán đổi hai giá trị mà không cần biến phụ trong JavaScript?

CSS Filters

Với CSS filters chúng ta có trong tại kha khá đồ chơi như trong photoshop để vẽ hoa vẽ lá trên trình duyệt. Filter cũng sẽ được thực hiện sau khi trình duyệt render xong DOM, thực hiện xong bước paint (cái này các bạn phải xem lại critical render path để rõ hơn), nghĩa là nếu ko được hỗ trợ bởi trình duyệt thì cũng ko tới mức bể layout

  • brightness();
  • contrast();
  • grayscale();
  • invert();
  • opacity();
  • saturate();
  • sepia();
  • hue-rotate();
  • blur();
  • drop-shadow();

Chúng ta ko có filter nào để thay đổi cụ thể một giá trị màu, chỉ có hue-rotate để chỉnh nhẹ cái màu đang hiển thị. May mắn là chúng ta có thể kết hợp nhiều giá trị filter cùng một lúc

.icon:hover {
  filter: grayscale(100%) sepia(100%);
}

Nếu một trong số các filter ko được hỗ trợ, thì nó nhẹ nhàng cho qua, chứ ko bỏ hết thuộc tính filter. Nếu bạn dùng photoshop rồi, cũng hiểu là thứ tự áp dụng các filter sẽ ảnh hưởng đến kết quả cuối cùng.

Những cách thay đổi giá trị fill của SVG khi hover

Để sử dụng hue-rotate chúng ta phải dùng một ảnh SVG có màu, lẽ nào bạn dùng ảnh gốc trắng đen rồi css đổ màu vào được?

Những cách thay đổi giá trị fill của SVG khi hover

Trước hết phải invert() cái hình xuống, chuyển thành dạng medium grey

.icon:hover {
  filter: invert(0.5)
}

Những cách thay đổi giá trị fill của SVG khi hover

Sau đó mới dùng sepia()

.icon:hover {
  filter: invert(0.5) sepia(1);
}

Những cách thay đổi giá trị fill của SVG khi hover

Tiếp đến là thêm màu sắc mình yêu thích

.icon:hover {
  filter: invert(0.5) sepia(1) hue-rotate(200deg);
}

Những cách thay đổi giá trị fill của SVG khi hover

Tinh chỉnh một chút nữa

.icon:hover {
  filter: 
    invert(0.5)
    sepia(1)
    hue-rotate(200deg)
    saturate(4)
    brightness(1);
}

Những cách thay đổi giá trị fill của SVG khi hover

Để dễ hình dung hơn, dùng tool này của tác giả, kéo thả thấy kết quả

Tuy nhiên đây cũng chỉ cho được kết quả là một màu tương đối, không chỉ định một màu cụ thể được

SVG filters

Nếu cần hỗ trợ nhiều trình duyệt hơn, màu sắc cụ thể hơn, dùng đến SVG

Không giống với CSS, chúng ta phải đổ mồ hôi sôi nước miếng mới làm được

<svg xmlns="<http://www.w3.org/2000/svg>" version="1.1">
  <defs>
    <filter id="id-of-your-filter">
      ...          
      ...
    </filter>
    ...
  </defs>
</svg>

Chúng ta định nghĩa bằng thẻ <filter />, thẻ này phải nằm trong thẻ <defs/>

Trong CSS chúng ta trỏ đến thằng filter ở trên như sau

.icon:hover {
  filter: url('assets/your-SVG.svg#id-of-your-filter');
}

Những filter có thể sử dụng

  • <feBlend>
  • <feColorMatrix>
  • <feComponentTransfer>
  • <feComposite>
  • <feConvolveMatrix>
  • <feDiffuseLighting>
  • <feDisplacementMap>
  • <feDropShadow>
  • <feFlood>
  • <feGaussianBlur>
  • <feImage>
  • <feMerge>
  • <feMorphology>
  • <feOffset>
  • <feSpecularLighting>
  • <feTile>
  • <feTurbulence>

Với yêu cầu đổi màu, chúng ta sẽ dùng feColorMatrix

<svg xmlns="<http://www.w3.org/2000/svg>" version="1.1">
  <defs>
    <filter id="id-of-your-filter">
      <feColorMatrix
        color-interpolation-filters="sRGB"
        type="matrix"
        values="1 0 0 0 0
                0 1 0 0 0
                0 0 1 0 0
                0 0 0 1 0 "/>
    </filter>
    ...
  </defs>
</svg>

Cùng xem xét kỹ hơn giá trị matrix chúng ta đã sử dụng ở trên

Những cách thay đổi giá trị fill của SVG khi hover

Các cột giá trị tương ứng là red, green, blue, alpha và multiplier. Chúng ta sẽ ko quan tâm đến giá trị multiplier với nhu cầu đổi màu, chỉ cần 4 giá trị ở đầu.

Những cách thay đổi giá trị fill của SVG khi hover

Ví dụ chúng ta muốn set giá trị rgba(0,128,128,1), chuyển nó về giá trị ma trận theo cách tính

Những cách thay đổi giá trị fill của SVG khi hover

Lưu ý: SVG filter không thực hiện được trên hình nền đen, nên nếu đang là hình đen thì invert nó thành trắng trước khi thực hiện

.icon:hover {
  filter: invert(100%) url('assets/your-SVG.svg#id-of-your-filter');
}

Tiếp tục sử dụng công cụ kéo thả thấy kết quả của tác giả nếu bạn ko siêng làm toán mẫu giáo

The Many Ways to Change an SVG Fill on Hover (and When to Use Them)

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

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

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

Cách viết CV English IT đẹp chuẩn dành cho lập trình viên

cv english it
cv english it

CV English IT với những tiêu chuẩn về format, đẹp chuẩn sẽ như thế nào? Liệu CV IT tiếng Anh của bản cần lưu ý những điểm nào? Đâu là các yếu tố giúp thu hút nhà tuyển dụng? Đừng quá lo lắng vì bài viết sau đây sẽ giúp bạn giải đáp các thắc mắc đó!

CV English IT là gì?

cv english it
IT CV English là gì?

CV có ý nghĩa quan trọng vì nó phản ánh sự thể hiện thông qua các trải nghiệm (Peformances) của mỗi ứng viên. No được là tấm vé giúp các nhà tuyển dụng IT hiểu rõ hơn về năng lực, kinh nghiệm, trình độ của bạn. Do vậy, bạn cần biết cách tạo điểm nhấn ch CV English IT (CV IT tiếng Anh) của mình.

Sức cạnh tranh của thị trường tuyển dụng đang ngày càng lớn dần hơn. Và tất nhiên, tương tự như sơ yếu lý lịch cho dân IT, CV IT Developer hay CV cho các vị trí khác nhau như Junior, Senior Developer, bạn cần có sự chọn lọc các thông tin để CV English IT của mình đạt chuẩn.

Bật mí cách viết CV hấp dẫn nhà tuyển dụng IT

  Mẫu CV IT Manager hoàn hảo cho ứng viên ngành IT

  Mẫu CV IT Administrator chuẩn nhất 2024

Trước khi đến với buổi phỏng vấn IT – Interview, bạn cần nắm bắt nghệ thuật khởi đầu. Đó được hiểu là cách thức làm nổi bật CV. Đồng thời, giúp CV English IT tạo ra sự thu hút đối với nhà tuyển dụng. Đây là cơ sở quan trọng giúp bạn nhanh chóng chinh phục nhà tuyển dụng.

Hiểu đúng về CV English IT (CV IT tiếng Anh)

  Mẫu IT Programmer CV ấn tượng cho lập trình viên

CV không đơn thuần là một lá đơn xin việc. Và ứng viên cần hiểu rõ tầm quan trọng của nó. CV là thứ văn bản giúp nhà tuyển dụng tiếp cận gián tiếp với bạn. Nó là cái nhìn đầu tiên. Và dấu ấn về bạn có đủ tạo nên sức hút hay không phụ thuộc 60-80% vào CV English IT. Thật không quá để nói CV góp phần không nhỏ vào quyết định bạn có được mời phỏng vấn hay không?

Đồng thời, viết CV giúp bạn định hình và có những trải nghiệm tốt hơn. Trường hợp bạn ứng tuyển các vị trí khác như freelancer it hay Senior Developer đều sẽ đạt hiệu quả ứng tuyển cao hơn.

Tạo CV IT tiếng Anh, chuẩn ATS miễn phí trên TopDev

Sự phân bố hoàn hảo trong một CV English IT

cv english it
Đâu là những yếu tố quan trọng mà nhà tuyển dụng xem xét trong CV?

Sau đây là những yếu tố mà nhà tuyển dụng IT tìm kiếm gắn với tỉ lệ cần có. Đây là phần trăm tương đối, các bạn có thể tham khảo khi viết CV IT của mình.

Xem thêm các vị tri tuyển dụng IT nổi bật tại Tech Avenue Solutions tuyển dụng

45%: Kinh nghiệm trong những công việc liên quan.

35%: Kỹ năng và trình độ chuyên môn (kiến thức)

25%: Dễ đọc

16%: Thành tích.

15%: Mục tiêu rõ ràng và những khát khao trong nghề nghiệp

14%: Văn phong, ngôn từ, chính tả

9%: Học vấn.

Có thể thấy 3 yếu tố kinh nghiệm (Experiences), kiến thức (Knowledge)kỹ năng (Skills) vẫn là bộ ba nhân được sự quan tâm lớn từ nhà tuyển dụng IT. Những tỉ lệ trên dù chỉ mang tính tương đối nhưng chắc chắn nó sẽ là một cơ sở cho bạn hoàn thiện hơn CV English IT của mình. Chẳng hạn như apply vị trí Mobile App Developer, bạn cần quan tâm nhiều hơn đến phần năng lực, các kiến thức chuyên sâu về lĩnh vực ấy. Tránh những thông tin không cần thiết vì nó sẽ làm nhiễu CV English IT (CV IT tiếng Anh) của bạn.

Lời kết

Việc đầu tư vào một CV là rất quan trọng. Không chỉ dừng lại ở hình thức, nội dung và tất tần tật mọi thứ cần được chỉn chu. Một CV English IT bắt mắt mà nội dung không có hệ thống, thiếu sự nhất quán, cách diễn đạt mơ hồ thì cũng chưa đủ trình lọt mắt xanh nhà tuyển dụng. TopDev hi vọng với những chia sẻ thông qua bài viết, các bạn sẽ bỏ túi cho mình những cách thức viết CV đẹp chuẩn và chuyên nghiệp hơn. 

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

Tạo CV online mới nhất tại đây

“Giải mã” sức hút Vietnam Web Summit 2020 vào dịp cuối năm | VWS2020

Gần một tháng xuất hiện trên Top những sự kiện công nghệ đáng tham dự nhất vào dịp cuối năm, Vietnam Web Summit 2020 (VWS2020) đến thời điểm hiện tại đã có những chủ đề gì do các Experts, Decision Makers, Leader và các C-levels mang lại?

Những đại diện từ Google, Heineken, Tiki, Moca, Lazada, Chotot, Ahamove,…cho đến các công ty công nghệ Amanotes, Knorex, Unity Technologies, NashTech, Cinnamon AI…đều xuất hiện trong “bữa tiệc” cuối năm mang đến những “gam màu” nóng lạnh khác nhau tại VWS2020, hãy xem qua “bàn tròn công nghệ” cuối năm sẽ có gì?

  "Quyền năng" dữ liệu trong Kỷ nguyên mới?! | VWS2020
  Lộ diện những "nhân vật" đầu tiên góp mặt tại Vietnam Web Summit 2020 | VWS2020

Với lượng topic lên đến con số hàng trăm, xoay quanh 6 nhóm chủ đề liên quan đến công nghệ web, VWS2020 hứa hẹn là điểm hẹn công nghệ hoành tráng nhất cuối năm 2020, nơi các tech-guys gặp gỡ và chia sẻ về những ứng dụng công nghệ mới và đón đầu xu hướng trong giai đoạn 5 năm tiếp theo!

==

LEAD THE AGE OF REVOLUTION TECHNOLOGIES

Vào tháng 12/2020, Vietnam Web Summit do TopDev tổ chức trở lại tại 2 thành phố TP.HCM và HN – nơi những ý tưởng sẽ gặp nhau và cùng đón đầu những xu hướng, công nghệ mới trong chặng đường 5 năm tiếp theo – một kỷ nguyên mới của công nghệ!

► Tìm hiểu thêm: www.vietnamwebsummit.com
► Đăng ký vé: www.vietnamwebsummit.com/ve
► Hồ Chí Minh: 11/12/2020 | Hà Nội: 18/12/2020

 

Hành trình từ ông chủ quán cafe đến một Professional Developer

java cơ bản
Hành trình từ ông chủ quán cafe đến một Professional Developer

 Tác giả: lucatardi

Giới thiệu

Tôi viết bài viết này với mong muốn mang đến cho các bạn trẻ đang trong hành trình theo đuổi ước mơ làm việc trong ngành IT, có thêm động lực để phấn đấu vươn tới đam mê của mình.

Từ một ông chủ quán cafe…

Khi 18 tuổi, tôi làm việc cho một quán cafe gần nhà. Sự hứng thú với công việc này khiến tôi nung nấu ước mơ mở được một tiệm cafe cho riêng mình. Sau khi tích cóp được một khoản tiền, tôi cũng đã mở được cho bản thân một cửa tiệm nho nhỏ và việc đầu tiên tôi làm là thiết kế website cho cửa tiệm của mình. Để bắt đầu, tôi đã tìm hiểu rất nhiều về kiến thức Java cơ bản và những ngôn ngữ lập trình khác để có căn bản.

Tôi chưa hề có kinh nghiệm nào liên quan đến việc thiết kế web và những gì giúp tôi chỉ là các video dạy làm web online cũng như học Java online trên mạng. Kết quả website tôi tạo ra là sự kết hợp từ rất nhiều các trang khác nhau. Tôi đã rất tự hào về sản phẩm này. Mãi đến bây giờ tôi mới biết trang web xấu xí đó chính là khởi đầu cho sự nghiệp Developer của mình sau này.

Hành trình theo đuổi công việc lập trình từ cách tìm hiểu Java cơ bản

Bắt đầu với thiết kế website

Khi mới bắt đầu học về code, điều khiến tôi thấy hứng thú nhất với nó là việc tôi có thể kiểm soát mọi thứ và tính logic đằng sau mỗi dòng code. Bắt đầu với Java cơ bản, tôi hiểu được những kiến thức cơ bản về lập trình mà mình cần biết để bắt đầu. Cứ thế tôi tìm đến nhiều trang web khác nhau (có cả freecodecamp.org) để học thêm. Nhờ vậy mà tôi đã design được website mới cho cửa hàng của mình.

học java online
Tôi bắt đầu con đường lập trình viên của mình

Sau vài tháng làm quen với code, tôi quyết định học lớp cử nhân Software Engineering. Ban ngày tôi làm việc tại quán cafe và học lập trình vào buổi tối. Có thể nói chuỗi ngày lúc đó của tôi là sự quanh quẩn giữa Capuchino và C++.

Xem thêm Tất tần tật về C và C++

Nhưng đến một ngày tôi chợt nghĩ về tôi của tương lai, và tôi lúc đó không thể nào hình dung nỗi về mình với vai trò là một chủ quán cafe. Những gì xuất hiện trong đầu tôi lúc đó đều liên quan đến lập trình. Vậy là, tôi quyết định nhượng lại quán cafe và bán đi tất cả những gì tôi có, bất chấp sự ngăn cản của gia đình và bạn bè. Tôi chuyển đến Ireland – nơi được xem là thiên đường cho sự nghiệp của các dev. Nơi mà tôi có thể học Java cơ bản để hiểu hơn về các source code, bộ sưu tập thư viện mã nguồn mở đa dạng hay nền tảng Javadocs xuất sắc của nó…

Hành trình mới tại Ireland với kiến thức Java cơ bản và rất nhiều thứ khác

Tôi bắt đầu các khóa học lập trình bằng tiếng Anh tại đây. Mỗi ngày tôi phải vật lộn giữa ngoại ngữ và khối kiến thức khổng lồ để hiểu được những gì mình đang học. Cố gắng của tôi đã được đền đáp bằng vị trí thực tập sinh đầu tiên với vai trò Front-end Developer. Nhưng việc thực tập này không có lương nên tôi phải làm thêm ở một quán bar để đủ chi phí trang trải cho bản thân mình.

Đây thật sự là một khoảng thời gian khó khăn đối với tôi. Mỗi tối tôi phải bưng bê hàng tá bao đá lên rất nhiều tầng lầu và nhiều công việc nặng nhọc khác. Tôi chỉ ngủ được vài tiếng mỗi đêm nên việc tập trung cho công việc ngày hôm sau ở công ty trở nên khó khăn hơn rất nhiều. Đã có lúc tôi muốn bỏ cuộc, tôi cảm thấy mông lung và khó khăn với tất cả mọi thứ xung quanh, tôi quên luôn cả mục tiêu ban đầu mình đặt ra khi đến đây là gì.

Nhưng tôi đã tiếp tục,

Tôi tiếp tục tìm kiếm những công việc khác.

học java cơ bản
Hành trình đến với trình Professional Developer thật sự không hề dễ dàng

Mãi sau này tôi mới biết, thật ra lúc đó mình đang chiến đấu với chính bản thân mình. Đó là quãng thời gian cực khổ mà bất cứ lập trình viên nào cũng phải trải qua, là cuộc chiến với sự tự tin vào kỹ năng làm việc của chính mình.

May mắn là tôi đã tin vào bản thân và tiếp tục. Kết quả là sau một thời gian tìm kiếm tôi đã có việc làm ở vị trí Web Developer. Công việc của tôi là hỗ trợ và tạo ra các tập lệnh Vanilla JavaScript để theo dõi người dùng trên các trang web. Nhờ sự chăm chỉ tìm hiểu về JavaScript cơ bản lúc trước mà tôi đã làm việc trơn tru hơn.

Xem thêm Có nên học Vanilla JavaScript? Chắc chắn rồi!

Từ đó đến nay tôi đã nhảy việc thêm một vài lần nữa và cuối cùng đã tìm được cho bản thân một công việc lập trình chính thức.

Kết luận

Rõ ràng đến bây giờ mọi thứ đã chứng minh rằng lựa chọn của tôi lúc đó là đúng đắn. Tôi đã trở thành một dev thực thụ trong công việc cũng như có thể pha một cốc Capuchino tuyệt vời. Hãy tin vào chính mình, đó là chìa khóa giúp bạn thành công và tìm được việc làm ở những công ty tốt như Gear Inc. chẳng hạn.

Việc làm developer hấp dẫn tại TopDev

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

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

Tips and Tricks khi sử dụng For loop trong Go

Tips and Tricks khi sử dụng For loop trong Go

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

Go cung cấp hai cách để lặp qua các phần tử của một mảng, slice và map. Nó là for và for range, nhiều người thường thích sử dụng for range hơn khi không cần phải quan tâm đến index.

  10 Add-on Google Sheets phải có dành cho các Recruiters

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

1. Lặp và lấy pointer của từng phần tử

Giả sử có một đoạn mã như dưới đây để lấy con trỏ của từng phần tử trong một mảng và tạo một mảng mới với con trỏ tương ứng

arr := [2]int{1, 2}
res := []*int{}
for _, v := range arr {
  fmt.Println(&v)
  res = append(res, &v)
}
//expect: 1 2
fmt.Println(*res[0],*res[1])
//but output: 2 2

Như kết quả trên cho thấy, output không như mong đợi. Nó chỉ in phần tử cuối cùng. Vấn đề là gì? Vấn đề tương tự này cũng gặp phải khi dùng cho slice và map.

Nếu bạn xem qua source code của go, thật dễ để nhận ra for range thực chất là for loop thêm mắm muối vào, nó vẫn sử dụng một vòng lặp for và trước tiên nó sẽ sao chép tất cả các phần tử của mảng và lặp qua chúng và gán từng chỉ số và giá trị cho một biến tạm, vì thế khi chúng ta lấy địa chỉ của pointer của value thì nó sẽ luôn là một giá trị dẫn đến kết quả phía trên luôn cùng giá trị.

// len_temp := len(range)
// range_temp := range
// for index_temp = 0; index_temp < len_temp; index_temp++ {
//     value_temp = range_temp[index_temp]
//     index = index_temp
//     value = value_temp
//     original body
//   }

Vậy làm sao để xử lí nó ?

Có 2 cách một là sử dụng index để lấy giá trị phần tử.

for k := range arr {
    res = append(res, &arr[k])
}

Hoặc là sử dụng biến local để copy pointer của value đó.

for _, v := range arr {
    // giá trị của v được gán vào một biến local mới v1
    v1 := v
    res = append(res, &v1)
}

2. Liệu vòng lặp dưới sẽ là vô tận ?

Giả sử có đoạn mã dưới đây lặp lại một mảng và mảng đó được thay đổi trong chính vòng lặp

v := []int{1, 2, 3}
for i := range v {
    v = append(v, i)
}

The answer is no. As explained earlier, when the loop begins, it will copy the original array to a new one and loop through the elements, hence when appending elements to the original array, the copied array actually doesn’t change.

Câu trả lời là không nếu bạn để ý (1) phía trên thì khi vòng lặp bắt đầu nó sẽ copy slice ra một slice mới là lặp trên đó, vì vậy các bạn có thay đổi v thì cũng không ảnh hưởng, nó sẽ chỉ lặp từng đó lần thôi.

Bạn có thể kiểm chứng bằng đoạn code dưới đây.

arr := []int{1, 2, 3}
for i,v := range arr {
   fmt.Println(i,v)
   arr = []int{}
}
fmt.Println(arr)

3. Vấn đề với việc lặp qua một mảng lớn.

var arr = [102400]int{1, 1, 1}
for i, n := range arr {
    // để ví dụ thì mình bỏ qua i và n
    _ = i
    _ = n
}

Vấn đề là nó sẽ tiêu tốn lượng mem khá lớn khi đầu tiên nó sẽ copy tất cả phần tử sang một mảng mới với số lượng phần tử (n) như mảng cũ. Mặc dù mình không dùng đến 102400 phần tử

Để giải quyết có hai cách sau

// lấy địa chỉ của mảng gốc và lặp
for i, n := range &arr

// tạo 1 slice có từ arr ban đầu để sử dụng ít bố nhớ hơn
for i, n := range arr[:]

4. Reset giá trị của mảng một cách hiệu quả với for range ?

var arr = [102400]int{1, 1, 1}
for i, _ := range &arr {
    arr[i] = 0
}

Câu trả lời là có, Go đã tối ưu hóa về việc đặt lại giá trị thành giá trị mặc định trong source code. Các bạn có thể xem qua issue này

// Lower n into runtime·memclr if possible, for
// fast zeroing of slices and arrays (issue 5373).
// Look for instances of
//
// for i := range a {
// 	a[i] = zero
// }
//
// in which the evaluation of a is side-effect-free.

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

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

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

Giải mã bí ẩn “system load” trên Linux

Giải mã bí ẩn

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

Trên các hệ điều hành UNIX-like (như Ubuntu, Fedora, Kali, OSX, *BSD…) Một thông số phổ biến khi theo dõi trạng thái hệ thống qua các công cụ thường ngày như topwuptime là load average hay đầy đủ là system load average.

  10 điều bạn có thể làm với Linux mà bạn không thể làm với Windows
  14 khóa học Tech miễn phí chất lượng từ MIT, Harvard, Linux...

Load biểu diễn ở dạng 3 số thực:

$ w | grep load
 17:12:47 up 3 days,  6:45,  1 user,  load average: 0.08, 0.23, 0.35
$ uptime
 17:13:42 up 3 days,  6:46,  1 user,  load average: 0.03, 0.19, 0.33
$ top -bn1 | head -n1
top - 17:17:41 up 3 days,  6:50,  1 user,  load average: 0.30, 0.17, 0.28

Tất cả đều có dạng:

0.30, 0.17, 0.28

Theo man 1 top giải thích, 3 con số này là system load trung bình trong 1, 5 và 15 phút vừa qua :

system load avg over the last 1, 5 and 15 minutes

Nhưng system load, là cái gì?

system load là gì

Khi nói về trạng thái của một máy tính, có quá nhiều thông số người ta có thể đưa ra: lượng RAM sử dụng, lượng ổ cứng còn, %CPU đang load, … khiến cho việc ta ngồi đoán cũng khó mà trúng system load là gì.

Theo man 1 uptime, system load avg là: trung bình của số lượng process/thread đang dùng hoặc chờ được dùng CPU (nằm trong run queue ), cùng với các process/thread đang đợi I/O (vd đọc, ghi ổ đĩa cứng). Con số trung bình này chưa được chia trung bình cho lượng CPU.

Phần giải thích tiếp trong man 1 uptime khá “rắc rối”, dịch tạm như sau:

khi load average = 1 trên máy chỉ có 1 CPU, nó có nghĩa là CPU luôn được sử dụng ( a single CPU system is loaded all the time) , nhưng trên máy có 4 CPU thì có nghĩa là 1 CPU sẽ chỉ được dùng 25% thời gian ( it was idle 75% of the time).

Rõ ràng đoạn này viết về thời lượng dùng CPU chứ không phải số lượng process như phần ngay trước nó viết. Và theo tác giả bài viết này thì chỗ này của manpage bị sai.

Để tìm khái niệm chính xác hơn, ta tìm về nguồn gốc mà cả 3 câu lệnh đều trả về 1 kết quả, trên Linux bản 4 trờ đi, các câu lệnh đó đều đọc thông tin từ 1 file: /proc/loadavg

proc – tin gì cũng có

/proc là nơi chứa các thông tin về các process, được Linux kernel ghi ra và cập nhập thường xuyên. Mọi thông tin bạn có thể theo dõi 1 process: câu lệnh chạy process, thư mục hoạt động, lượng RAM sử dụng … đều được Linux kernel ghi ra /proc, các công cụ chỉ việc mở file trong đó và đọc nội dung.

Đây là nội dung của /proc/loadavg trên máy tác giả:

$ cat /proc/loadavg 
0.56 0.63 0.64 2/607 3415
$ uptime 
 14:56:19 up 4 days,  4:29,  1 user,  load average: 0.56, 0.63, 0.64

ngoài 3 con số load avg 1, 5, 15 đã nhắc tới ở trên, 2 trường còn lại :

  • 2/607: 2 là số process/thread đang chạy hoặc đang đợi chạy, được kernel xếp lịch cho. 607 là số process/thread đang tồn tại trên hệ thống.
  • 3415: PID của process mới nhất trên hệ thống.

man 5 proc có giải thích 3 con số load giống như man 1 uptime:

The first three fields in this file are load average figures giving the number of jobs in the run queue (state R) or waiting for disk I/O (state D) averaged over 1, 5, and 15 minutes.

system load được tính thế nào?

Trong các manpage không giải thích cách tính công thức này, và đây rõ ràng là là một công thức thần bí. Ta sẽ chui vào sourcecode của Linux để xem cách tính loadavg, có thể xem file này tại kernel/sched/loadavg.c

Trước khi đi chi tiết vào công thức kinh khủng này, hãy chú ý đến dòng comment ngay đầu file:

* This file contains the magic bits required to compute the global loadavg
* figure. Its a silly number but people think its important. We go through
* great pains to make it work on big machines and tickless kernels.

Tác giả những dòng code tính loadavg cho rằng đây là một con số ngu ngốc, nhưng nhiều người lại coi nó là quan trọng.

Nói nôm na, nó được tính bằng 1 - 1/e ~ 63 % số load của khoảng thời gian vừa qua (1, 5 hay 15 phút) + 1/3 ~ 37% của load trung bình từ khi bật máy (trừ khoảng thời gian vừa qua) theo Wiki. Chi tiết code tính lằng nhằng này có thể xem tại linux source code (good luck & have fun ;)).

system load có ý nghĩa gì

Khi system load average tăng cao, nó có nghĩa trong khoảng thời gian vừa qua, có nhiều process/thread đang dùng hay chờ được dùng CPU, hoặc đợi thực hiện I/O (đọc ghi ổ cứng/mạng), nó không nhất thiết nghĩa là CPU bị dùng hết khả năng (tức không nhất thiết CPU phải luôn 100% nếu loadavg là 1.00 trên máy có 1 CPU).

Xem một ví dụ có loadavg > 50.00, trong khi CPU và ổ cứng đều ít được dùng, lý do là bởi nhiều process/thread xếp hàng được xử lý khi dùng mạng.

Truy cập loadavg từ Python

Có thể mở trực tiếp file /proc/loadavg – chỉ hoạt động trên Linux, không hoạt động trên OSX, BSD… hoặc dùng function có sẵn trong module os:

In [7]: import os

In [8]: os.getloadavg()
Out[8]: (0.76, 0.87, 0.81)

Dù có 2 cách làm cho ra cùng kết quả, cách sử dụng thư viện có sẵn luôn được khuyên dùng với lập trình viên, vì nó xử lý được trên các hệ điều hành khác nhau, không quá quan tâm đến phía dưới là gì, khiến code trở nên “portable” hơn (có thể chạy ở trên nhiều nền tảng).

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

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

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

HTML cơ bản toàn tập cho người mới phần 2

HTML cơ bản toàn tập cho người mới phần 2

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

Ở phần trước mình đã hướng dẫn cho các bạn các kiến thức về các thẻ hay dùng trong HTML nhất, tuy nhiên trong HTML thì còn rất nhiều thẻ khác và đi kèm với chúng là những thuộc tính nữa. Trong bài ngày hôm nay chúng ta sẽ cùng nhau khám phá và tìm hiểu thêm các thẻ trong form và table nhé. Bắt đầu thôi nào.

# Các thẻ về form

## Thẻ form

Là thẻ block, thẻ này thường được dùng khi các bạn muốn gửi dữ liệu tới server như đăng nhập, đăng ký, cập nhật thông tin thông qua việc submit form. Trong thẻ form này có nhiều thuộc tính mà các bạn cần nắm rõ như sau.

  5 bước tìm hiểu sơ lược thành phần một web HTML động
  Cách để tạo một Switch trên iPhone bằng HTML và CSS
  • Thuộc tính action truyền vào đường dẫn hoặc file xử lý thông tin của form khi được người dùng nhấn nút submit
  • Thuộc tính method thì nó liên quan tới các phương thức HTTP khi submit form, nếu các bạn học cơ bản tới đây thì chưa cần phải hiểu quá những cái này, sau này các bạn học tới Javascript rồi làm việc với API Server thì các bạn sẽ nắm rõ mấy này hơn
  • Thuộc tính name giúp phân biệt giữa các form với nhau nếu các bạn sử dụng nhiều form trong một trang web
  • Thuộc tính autocomplete có giá trị mặc định là on nghĩa là nó sẽ hiển thị gợi ý khi các bạn đăng nhập hay đăng ký các bạn đưa chuột vào ô gõ thì nó gợi ý ra email chẳng hạn thì đó gọi là autocomplete, nếu các bạn muốn tắt nó đi thì chỉ cần thiết lập autocomplete="off" là được
  • Thuộc tính enctype định nghĩa các kiểu dữ liệu mà sẽ được gửi tới server, như là chữ, hay html hay là hình ảnh…
<form name="signup" action="/signup" method="post" autocomplete="off" enctype="text/plain"></form>
HTML cơ bản toàn tập cho người mới phần 2
Minh hoạ một form cơ bản
## Thẻ input

Là thẻ inline, và là thẻ tự đóng, thẻ này thường được dùng bên trong thẻ form ở trên, thẻ này có nhiều thuộc tính và trong các thuộc tính thì lại có rất nhiều giá trị mà các bạn nên biết và nắm rõ cách dùng nhé.

Đầu tiên là thuộc tính type, trong thuộc tính này có các giá trị như là

  • Giá trị text, cho phép người dùng nhập vào kí tự nào cũng được như chữ, số, email…
  • Giá trị email khá giống giá trị text tuy nhiên trình duyệt sẽ hiểu đây là kiểu email cho nên buộc người dùng phải nhập vào email hợp lệ, khi ở trên thiết bị điện thoại thì bàn phím dành cho email sẽ hiển thị lên với dấu @ mà các bạn có thể thử
  • Giá trị number thì phải nhập vào là số như số nguyên hoặc số lẻ, trên thiết bị điện thoại thì bàn phím số sẽ hiển thị lên tương ứng
  • Giá trị password để khi người dùng nhập mật khẩu sẽ hiển thị dấu *
  • Giá trị date sẽ hiển thị ngày khi người dùng nhập vào ngày tháng năm
  • Giá trị time sẽ hiển thị thời gian khi người dùng muốn chọn thời gian
  • Giá trị file để người dùng muốn upload file lên ví dụ như cập nhật avatar thì phải có input là file để người dùng chọn được ảnh họ muốn
  • Giá trị checkbox là nút check cho phép người dùng chọn hoặc bỏ chọn, hoặc có thể chọn nhiều cái, như khi liệt kê danh sách sở thích và người dùng có thể chọn nhiều cái trong đó hoặc không chọn cái nào
  • Giá trị radio cũng là nút check nhưng chỉ được chọn 1 trong 2 hoặc 1 trong nhiều thứ chứ không được chọn nhiều ví dụ khi người dùng chọn giới tính nam hoặc nữ
  • Giá trị submit sẽ làm cho nó trơ thành nút submit để người dùng khi điền xong thông tin và nhấn nút này hoặc nhấn nút Enter thì form sẽ submit dữ liệu.
<input type="email"/>

Tiếp theo là thuộc tính placeholder, thuộc tính này giúp tạo ra một lớp chữ mờ bên trong input khi mà người dùng chưa nhập nội dung vào

<input type="email" placeholder="Email"/>
HTML cơ bản toàn tập cho người mới phần 2
Placeholder

Thuộc tính value tức là giá trị của input để khi submit form thì người ta sẽ lấy những giá trị này đưa lên server xử lý, tuy nhiên làm sao để lấy được những giá trị này thì phải dựa vào thuộc tính name bên dưới đây.

Thuộc tính name giúp phân biệt giữa các input với nhau và cũng rất quan trọng, nó được dùng khi làm việc với Javascript để lấy dữ liệu từ các input dựa vào thuộc tính name này. Và khi làm việc với input có type là checkbox hay radio thì thuộc tính name này truyền vào giá trị cho các checkbox hay radio cùng tên để có thể lấy dữ liệu chính xác ví dụ nếu các bạn làm với radio chọn giới tính mà các bạn code như này

<input type="radio" value="male"/>
<input type="radio" value="female"/>

Các bạn không truyền vào name hoặc truyền vào name khác nhau thì khi submit form nó sẽ hiểu là 2 giá trị khác nhau do name khác nhau và người dùng có thể chọn cả 2 giá trị cả nam lẫn nữ trong khi đó bạn muốn chỉ chọn một trong hai thôi cho nên để khắc phục thì các bạn thêm trường name vào và giống nhau như sau:

<input type="radio" value="male" name="gender"/>
<input type="radio" value="female" name="gender"/>

Thuộc tính required khi mà các bạn muốn trường đó buộc người dùng phải nhập vào nếu không nhập vào thì sẽ không submit form được

<input type="email" placeholder="Email" required/>

Thuộc tính disabled không cho phép người dùng nhấn vào input hay là làm gì cả, thuộc tính này các bạn sẽ dùng khi muốn cho người ta thấy được giá trị nhưng không thể làm gì chẳng hạn những hệ thống người ta không cho bạn đổi email chẳng hạn thì người sẽ thêm thuộc tính này vào

<input type="email" placeholder="Email" disabled/>
HTML cơ bản toàn tập cho người mới phần 2
Input bị disabled

Thuộc tính min dùng với input có type là number có nghĩa là số nhỏ nhất mà người dùng phải nhập vào ví dụ nhập tuổi các bạn muốn tuổi nhỏ nhất phải là 18 thì sẽ có min=”18″

<input type="number" min="18" name="age"/>

Ngược lại thuộc tính min đó chính là thuộc tính max, nghĩa là số lớn nhất mà người dùng có thể nhập vào ví dụ tuổi lớn nhất là 100 thôi chẳng hạn

<input type="number" min="18" max="100" name="age"/>

Tương tự cho input type là text hay email chẳng hạn bạn muốn người dùng nhập vào tối thiểu bao nhiêu ký tự hay tối đa bao nhiêu ký tự thì chúng ta sẽ dùng 2 thuộc tính tương ứng là minlength và maxlength nhé

<input type="text" minlength="10" maxlength="200"/>

Thuộc tính readonly thì na ná với disabled là không làm được gì cái input cả, chỉ có cái khác là nó vẫn có thể focus còn disabled thì không, khi submit form thì input có readonly vẫn sẽ được gửi dữ liệu tới server còn input có disabled thì không.

<input type="number" min="18" readonly/>
HTML cơ bản toàn tập cho người mới phần 2
Input đang dùng readonly

Ngoài ra input vẫn sử dụng được các thuộc tính thông dụng như class hoặc id nhé các bạn. Và thuộc tính id trong input hay được dùng khi làm việc với thẻ Label dưới đây

## Thẻ label

Là thẻ inline, thẻ này thường được dùng với input, textarea để khi người dùng nhấn vào nó thì nó sẽ tự động trỏ tới input hay textarea để focus vào chúng thông qua thuộc tính for trong label

<label for="name">Name</label>

Thuộc tính for này sẽ trỏ tới id của input cho nên trong input cần có id tương ứng với giá trị trong for của label như sau, ở đây for có giá trị là name và input có id cũng là name, lưu ý id không được trùng nhau nhé

<label for="name">Name</label>
<input type="text" id="name" placeholder="Please enter your name..."/>
HTML cơ bản toàn tập cho người mới phần 2
Thẻ label trong thực tế
## Thẻ textarea

Là thẻ inline, thẻ này cũng giống thẻ input là đều có các thuộc tính như input, điểm khác ở đây là textarea cho phép người dùng nhập vào nhiều nội dung và có thể enter xuống hàng còn input thì không được. Nó thường được dùng khi cho người dùng nhập vào mô tả thông tin cá nhân, hay là soạn thảo bài viết…

<textarea name="content" placeholder="Type something if you want"></textarea>
Thẻ textarea
## Thẻ button

Là thẻ inline, thẻ này được dùng trong form khi người dùng nhấn vào để gửi dữ liệu đã nhập vào hoặc xoá hết dữ liệu. Thẻ button này có thuộc tính type với 3 giá trị là submit để submit dữ liệu và reset để xoá hết dữ liệu trong form khi nhập vào(khá nguy hiểm), cuối cùng là button sẽ không có tác dụng gì khi nhấn vào.

Thẻ button cũng có thuộc tính disabled nghĩa là không cho phép người dùng nhấn vào hay làm gì cả, kiểu như sau này các bạn làm việc với Javascript các bạn check nếu người dùng nhập đầy đủ thông tin thì mới cho nhấn chẳng hạn thì ban đầu sẽ có thuộc tính disabled, khi người dùng nhập hợp lệ thì mới xoá thuộc tính disabled đi.

<button type="submit" class="form-submit">Sign in</button>
HTML cơ bản toàn tập cho người mới phần 2
Thẻ button
## Thẻ fieldset

Là thẻ khi các bạn muốn gom nhóm các trường lại như input, button, textarea vào chung rồi disabled một nhóm luôn thay vì disabled từng cái.

<form action="/subscribe" method="post">
  <fieldset disabled>
    <legend>Subscribe to the Newsletter</legend>
    <input type="email" name="email">
    <button>Ok</button>
  </fieldset>
</form>
## Thẻ select option

Là thẻ block, thẻ này sẽ hiển thị dưới dạng dropdown cho phép các bạn chọn một danh sách được xổ ra trong thẻ select này sẽ có các thẻ option đi kèm với đó là value tương ứng cho option mà các bạn chọn. Trong thẻ select cũng có trường name như những thẻ input vì để phân biệt và sử dụng trong form nha.

<select name="option">
  <option value="Option A">Option A</option>
  <option value="Option B">Option B</option>
  <option value="Option C">Option C</option>
</select>

Tuy nhiên select mặc định không được đẹp cho nên thường người ta sẽ tuỳ biến lại bằng các thẻ HTML khác như div, ul li thay vì dùng select option mặc định(do mặc định không tuỳ biến với CSS được) rồi sau đó dùng Javascript để lấy dữ liệu, và tuỳ biến lại thì sẽ đẹp hơn mặc định nhiều ví dụ

HTML cơ bản toàn tập cho người mới phần 2
Custom dropdown
## Sự khác nhau giữa input type submit và button type submit

Nhiều bạn có hỏi là 2 thẻ này khác nhau ra sao thì mình xin giải thích cho các bạn biết nhen. Khi các bạn dùng input type submit thì nó là thẻ tự đóng cho nên không truyền HTML vào giữa được, còn thẻ button thì các bạn có thể chèn HTML vào giữa như sau

<input type="submit" value="Submit"/>
<button type="submit"><i class="fa fa-plus"></i><span>Submit</span></button>

Thẻ button thì có thể dùng pseudo như :before hay :after còn input type submit thì không. Do vậy thường khi làm việc với form đa số sẽ dùng thẻ button hơn vì có thể tuỳ biến được nhiều hơn như hình dưới này mình dùng thẻ button và có loading bên trong khi submit form.

HTML cơ bản toàn tập cho người mới phần 2
Button loading

# Tạm kết

Phần này chỉ nói đến các thẻ trong Form thôi mà cũng nhiều kiến thức phết. Hi vọng nó sẽ có ích cho các bạn mới học nha. Ở phần tiếp theo mình sẽ nói đến các thẻ khác như thẻ về bảng, các thẻ meta….. Chúc các bạn học tập tốt và một ngày tốt lành nhen.

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

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

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

Bài phỏng vấn Evan You

Bài phỏng vấn Evan You

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

Chào Evan, rất vui được nói chuyện với anh hôm nay! Hãy bắt đầu bằng câu hỏi: làm một công việc full time bằng Patreon chắc khá khác biệt, làm sao anh có thể cân bằng giữa công việc và cuộc sống để không bị kiệt sức

Tôi cố gắng đi theo một lịch trình cố định hằng ngày, thậm chí đang làm việc tại nhà và “tự thuê mình”. Có con thật sự giúp tôi rất nhiều vì tôi phải dành nhiều thời gian hơn với gia đình khi tôi không làm việc. Điều khác cũng khá quan trọng, khi thấy cần tôi sẽ nghỉ phép khá lâu, điều này sẽ khó nếu bạn đang làm việc full time ở một công ty

Vue 3 mới ra mắt, anh có nghỉ phép không hay đã có kế hoạch cho version tiếp theo của Vite

  'Toát mồ hôi' phỏng vấn tuyển dụng vào Apple
  8 câu hỏi phỏng vấn dành cho các lập trình viên Mobile app

Lúc nào tôi cũng có backlog dài lắm. Hiện tại với Vite mục tiêu chính là giúp nó stable hơn, hệ thống khá mới và mọi người đang sử dụng nó trong nhiều tình huống mà tôi không thiết kế ngay từ đầu, nên chúng tôi cần thêm thời gian để xác định sẽ phát triển tiếp những gì. Hiện tại cũng có khá nhiều ý tưởng đang chờ cho Vue 3.1. Tất nhiên tôi sẽ nghĩ khá lâu đấy, tôi cần phải “sạc pin” lại.

Trước đây, với nền tảng là người có kiến thức Art History khi gia nhập Google Creative Lab ở vị trí creative technologist, có bao giờ anh cảm thấy thiếu kiến thức toán học, thuật toán, cấu trúc dữ liệu khi làm việc với Vue? Chúng ta có thật sự cần nền tảng khoa học máy tính để trở thành lập trình viên?

Thật lòng mà nói là không, cá nhân tôi nghĩ, Vue, hay frontend framework nói chung, không cần có chuyên môn quá sâu về toán/thuật toán (nếu đem so với database). Tôi vẫn nghĩ bản thân mình không quá mạnh về thuật toán, cấu trúc dữ liệu. Sẽ rất tốt nếu tôi có thể mạnh những thứ đó, tuy nhiên khi xây dựng một framework phổ biến bạn cần rất nhiều thứ phải làm lắm và đặc biệt là hiểu người sử dụng nó, thiết kế các API hợp lý, xây dựng cộng đồng, cam kết hỗ trợ, bảo trì nó trong thời gian dài.

Tôi nghĩ chúng ta không nên cảm thấy không đủ xứng đáng để trở thành lập trình viên vì chúng ta không trãi qua các lớp đào tạo khoa học máy tính, điều nay không đồng nghĩa tôi khuyên bạn nên phớt lờ những kiến thức đó, nó vẫn rất hữu ích. Tôi trãi qua con đường khá thực dụng, tôi làm sai rất nhiều, rồi sau đó thấy sự cần thiết và học cách để làm tốt hơn.

Với khá nhiều công nghệ hiện tại như Nuxt.js, JAMstack, lập trình viên khá hứng thú với việc tập trung toàn bộ vào frontend và sử dụng rất ít Backend. Anh nghĩ thế nào về cách tiếp cận “no-backend” hoặc “fullstack”?

Tôi thấy sản phẩm sẽ định hướng công nghệ sử dụng chứ không phải chiều ngược lại. Lập trình viên đi theo hướng công nghệ nào đó bởi vì nó phù hợp với sản phẩm họ đang xây dựng. Rõ ràng “no-backend” không phải là viên đạn bạc nhưng nó sẽ rất phù hợp với một nhóm các ứng dụng cụ thể

Vue được viết lại rất nhiều lần. Nếu có thể quay về thời điểm ban đầu, một lời khuyên về công nghệ cho những người trẻ thì nó sẽ là gì?

Làm cách nào để tách biệt và decouple các module internal tốt hơn

Những năm gần đây, chúng ta thấy sự phát triển song song giữa JavaScript và TypeScript. Anh sẽ đặt cược vào tương lai nào: liệu chúng ta sẽ có type được thêm vào trong JavaScript hay TypeScript sẽ thay thế luôn JavaScript hay gì đó khác?

Tôi nghĩ việc thêm type vào JS sẽ còn rất rất lâu – Tôi không nghĩ nó sẽ xảy ra luôn đấy chứ, bởi vì thiết kế một hệ thống type bởi cộng đồng (và được đánh giá bởi TC39) khá là… không khả thi. TypeScript cũng sẽ không thay thế JS vì nó được thiết kế là một superset của JS. Cá nhân tôi nghĩ có JS và TS (superset với Type) cùng phát triển đồng thời là cách tiếp cận thực tế và sẽ như vậy trong tương lai.

Những người sử dụng Vue đã lên hàng triệu developer. Anh nghĩ cách nào tốt nhất để đánh giá tầm ảnh hưởng của một công nghệ. Số câu hỏi trên Stack Overflow, sao của Github, số lượt truy cập, hay số người sử dụng trong các công ty tập đoàn (mạng bị tách biệt không thể có thông tin được), những cá nhân bị “ép” sử dụng bởi quyết định của cấp trên. Tất cả những nhân tố đó có ảnh hưởng thế nào đến mức độ phổ biến của một công nghệ?

Đây là một vấn đề bản chất của phần mềm nguồn mở, người sử dụng không cần phải báo cáo việc họ sử dụng và chúng ta cũng không có cách nào có track việc đó một cách chính xác. Đó là lý do tại sao tôi xem số lượng người sử dụng công cụ DevTool của Vue là con số tương đối chính xác vì nó biết chính xác tài khoản nào đang sử dụng.

Làm việc với tree-shaking khá nhiều trong Vue.js 3. Anh thấy tại sao tree-shaking mất quá nhiều thời gian để áp dụng vào các framework hiện đại? Bộ có khó khăn gì với nó à?

Cách làm việc của tree-shaking phụ thuộc vào việc source code tổ chức theo một cách rất cụ thể – nghĩa là nó làm việc tốt nhất khi code được viết (và các API được thiết kế) với tâm thế tree-shaking ngay từ ngày đầu tiên. Rất khó để một source code đã có trước sống hòa thuận với tree-shaking, hoặc phải thay đổi rất nhiều trong các API đã có, hoặc refactor gần như toàn bộ (rủi ro sẽ rất cao).

Đề xuất Function-based component API trong Vue 3 nhận được khá nhiều thảo luận trong cộng đồng. Anh có suy nghĩ nào khác muốn chia sẻ với các lập trình viên?

Đa phần phản hồi chúng tôi nghe được là việc sợ chúng tôi sẽ ngừng hỗ trợ các API của Vue 2.x hiện tại, và rõ ràng là sai lầm nếu chúng tôi làm việc đó. Là tác giả, người bảo trì hằng ngày chúng tôi tiếp xúc với những thay đổi, những ý tưởng mới sớm hơn ai hết, thường kéo theo việc chúng tôi sẽ quên mất tầm quan trọng của việc hỗ trợ tương thích ngược. Chúng tôi hiểu rằng người sử dụng sẽ không vui vẻ gì nếu chuyện đó xảy ra.

Điều có thể rút ra là, chúng ta cần biết người dùng cần gì – thường không dễ để biết được và phải đi theo những cách rất khó khăn, và bạn cần sẵn sàng lắng nghe một cách tích cực chủ động.

Vue được sử dụng trong các doanh nghiệp nhỏ, vừa và thậm chí các công ty triệu đô. Louis Vuitton and NASA đang sử dụng Vue. Có ví dụ nào anh đề nghị mọi người nên tham khảo như một ví dụ sử dụng thực tế

Vấn đề là các dự án thực tế đủ phức tạp lại không phải open-source. Tôi nghĩ có thể xem source của Vue DevTools và Vue CLI UI nếu bạn cần một ví dụ đủ phức tạp, cả hai đều có giao diện không bình thường được viết bằng Vue, mặc dù nó không phải vấn đề mà các web app thường gặp.

Bài phỏng vấn của evrone

Users don’t like things being taken away. The takeaway is you need to understand what your users want — it’s not that easy and sometimes you will get that information the hard way, but you need to be willing to listen regardless.

Happy coding 🎉🙌

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

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

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