Home Blog Page 190

Bí kíp chinh phục tất cả nhà tuyển dụng IT trong vòng phỏng vấn (Phần 1)

Mặc dù đã đạt được điểm số cao trong khóa học CS101 thuật toán và môn Data Structures ở trường đại học, tôi vẫn thấy rùng mình với ý nghĩ phải trải qua một cuộc phỏng vấn lập trình với trọng tâm hướng vào các thuật toán và khá lấn cấn khi tìm kinh nghiệm phỏng vấn IT. 

Do đó tôi đã dành ba tháng sau khi ra trường để tìm hiểu cách cải thiện kỹ năng trả lời các buổi phỏng vấn của mình và thành quả là nhận được đề nghị từ các công ty công nghệ lớn. Trong bài viết này, tôi sẽ chia sẻ những mẹo mà mình đã dùng trong quá trình đi phỏng vấn. Xin lưu ý là những câu hỏi theo khuôn mẫu sẽ không nằm trong phạm vi của bài viết này.

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

  Những câu hỏi phỏng vấn về GIT cần nhớ ngay

Hẳn bạn cũng biết việc có nhiều khái niệm thuật toán xuất hiện trong buổi phỏng vấn lại ít được dùng tới khi bạn đi làm, nhưng vẫn được hỏi để kiểm tra nền tảng cơ bản. Đương nhiên, tôi cũng đã quên khá nhiều về các thuật toán và cấu trúc dữ liệu này, vốn được chủ yếu được dạy cho những sinh viên năm nhất và năm thứ hai đại học.

Song song đó, thật căng thẳng khi phải viết code trong cuộc phỏng vấn, khi có ai đó xem xét kỹ mọi phím tắt mà bạn thực hiện. Điều tồi tệ hơn là với tư cách là người được phỏng vấn, bạn còn cần phải truyền đạt và nói ra suy luận của mình ngay trong buổi phỏng vấn.

Tôi từng nghĩ rằng việc có thể suy nghĩ, viết code và giao tiếp cùng lúc là một điều không thể, cho đến khi tôi nhận ra rằng phỏng vấn là một kỹ năng mà bạn có thể đạt được tốt hơn bằng cách học tập, chuẩn bị và tập dợt cho nó.

Vì vậy mà có thể nói quá trình tìm kiếm việc làm gần đây của tôi đã giúp cải thiện kỹ năng phỏng vấn của mình rất nhiều. Rất nhiều các lập trình viên front-end than phiền về việc các cuộc phỏng vấn kỹ thuật có thể bao gồm những kỹ năng không liên quan đến quá trình phát triển front-end. Ví dụ, viết một thuật toán giải quyết mê cung và kết hợp hai danh sách các số đã được sắp xếp. Cũng là một kỹ sư front-end bản thân mình, tôi có thể cảm thông với họ.

Front end là một lĩnh vực chuyên biệt nơi các kỹ sư phải quan tâm đến nhiều vấn đề liên quan đến việc tương thích với trình duyệt, Document Object Model, hiệu suất JavaScript, bố cục CSS, v.v. Vì thế mà khá ít khi các lập trình viên front-end bị đòi hỏi phải thực hiện một số thuật toán phức tạp trong các cuộc phỏng vấn.

Thật không may, các quy tắc được đặt ra bởi các công ty, không phải bởi các ứng cử viên. Vì thế mà các khái niệm khoa học máy tính nói chung như thuật toán, design pattern, cấu trúc dữ liệu đều phải cần nắm vững. Nếu bạn muốn công việc, bạn phải chơi theo các quy tắc được thiết lập bởi các nhà tuyển dụng – nói cách khác, bạn phải cải thiện kỹ năng trả lời phỏng vấn của mình!

Bí kíp chinh phục tất cả nhà tuyển dụng IT trong vòng phỏng vấn (Phần 1)

Bài viết này được chia thành hai phần như sau. Hãy thoải mái bỏ qua phần bạn không quan tâm.

Phân tích các cuộc phỏng vấn lập trình và cách chuẩn bị cho chúng.

Lời khuyên hữu ích cho mỗi chủ đề thuật toán (arrays, trees, dynamic programming, vv), cùng với các câu hỏi thực hành của LeetCode để nắm vững các khái niệm cốt lõi.

Bí kíp chinh phục tất cả nhà tuyển dụng IT trong vòng phỏng vấn (Phần 1)

Chọn một ngôn ngữ lập trình phù hợp

Trước khi làm bất cứ điều gì khác, bạn sẽ cần phải chọn một ngôn ngữ lập trình để có thể thực hiện một cuộc phỏng vấn. Hầu hết các công ty sẽ cho phép bạn viết code bằng ngôn ngữ tự chọn ngoài một ngoại lệ duy nhất tôi biết là Google. Họ chỉ cho phép các ứng cử viên của họ chọn Java, C ++, Python, Go hoặc JavaScript. Do đó, tôi khuyên bạn chỉ nên sử dụng một ngôn ngữ mà bản thân đã rất quen thuộc, chứ không phải là một lựa chọn mới với bạn nhưng được công ty sử dụng rộng rãi.

Có một số ngôn ngữ phù hợp hơn những ngôn ngữ khác cho các cuộc phỏng vấn lập trình. Cũng như có một số mà bạn sẽ muốn tránh bằng mọi giá. Từ kinh nghiệm của tôi với tư cách là một người đã phỏng vấn nhiều lập trình viên, hầu hết các ứng cử viên đều chọn Python hoặc Java. Ngoài ra thì JavaScript, Ruby và C ++ là những lựa chọn không tồi. Tuy vậy, tôi sẽ tránh các ngôn ngữ cấp thấp hơn như C hoặc Go vì chúng thiếu các tính năng thư viện chuẩn và cấu trúc dữ liệu.

Theo ý kiến của cá nhân tôi thì Python là sự lựa chọn tốt nhất cho việc viết các thuật toán khi bạn đi phỏng vấn. Đó là vì nó vô cùng gọn gàng và có một thư viện rất lớn về các tính năng và cấu trúc dữ liệu. Mặt khác, Python còn sử dụng các API nhất quán và hoạt động được trên các cấu trúc dữ liệu khác nhau, chẳng hạn như len()for ... in ... và cắt ký hiệu trên chuỗi (chuỗi, list và bộ dữ liệu). Hay còn có thể lấy phần tử cuối cùng trong một chuỗi là  arr[-1] , và đảo ngược nó với cách thức vô cùng đơn giản là arr[::-1].Vì vậy mà bạn có thể đạt được rất nhiều thứ với các cú pháp tối thiểu trong Python.

Java cũng là một lựa chọn tốt. Nhưng bởi vì bạn sẽ phải liên tục khai báo các type trong code của mình nên sẽ làm chậm tốc độ mà bạn viết code. Vấn đề này sẽ càng rõ ràng hơn khi bạn phải viết trên một tấm bảng hoặc ra giấy trong các cuộc phỏng vấn.

Lý do chọn hoặc không chọn C ++ thì cũng tương tự như Java. Nói chung, Python, Java và C ++ là những lựa chọn tốt. Nếu bạn đã sử dụng Java một thời gian, và không có thời gian để làm quen với một ngôn ngữ khác, tôi khuyên bạn nên cứ gắn bó với Java thay vì chọn Python. Điều này giúp bạn tránh tình trạng phải sử dụng một ngôn ngữ mà mình chẳng hề đụng tới chỉ cho các cuộc phỏng vấn.

Một ngoại lệ cho việc cho phép ứng cử viên “chọn bất kỳ ngôn ngữ lập trình nào mà họ muốn” là khi cuộc phỏng vấn dành cho vị trí cụ thể, chẳng hạn như vai trò trong front-end, iOS hoặc Android. Khi đó bạn sẽ cần phải quen thuộc với các thuật toán trong JavaScript, Objective-C, Swift hoặc Java.

Nếu bạn cần sử dụng cấu trúc dữ liệu mà ngôn ngữ lại không hỗ trợ, chẳng hạn như queue hoặc heap trong JavaScript, hãy hỏi người phỏng vấn nếu bạn có thể giả định rằng bạn có cấu trúc dữ liệu triển khai các phương pháp nhất định với độ phức tạp thời gian cụ thể. Nếu việc thực hiện cấu trúc dữ liệu đó không quan trọng để giải quyết vấn đề, người phỏng vấn thường sẽ cho phép. Trong thực tế, việc nhận thức được các cấu trúc dữ liệu hiện có và lựa chọn các cấu trúc thích hợp để giải quyết vấn đề trong tầm tay là quan trọng hơn việc biết các chi tiết triển khai phức tạp.

Ôn lại những gì mình đã học được

Nếu bạn đã ra khỏi trường đại học một thời gian, bạn nên xem lại các nguyên tắc cơ bản về CS. Hãy chịu khó coi qua các ghi chú khi còn đi học của mình và luyện giải các vấn đề thuật toán từ LeetCode và Cracking the Coding Interview.

Kho lưu trữ các câu hỏi phỏng vấn interviews repository này bởi Kevin Naughton Jr. sẽ giúp cho bạn nhanh chóng nắm vững các khái niệm nền tảng và cơ bản.

Ngoài ra, khóa học basecs của Vaidehi Joshi cũng là một nguồn tài nguyên tuyệt vời và dễ nuốt để nắm lại các cấu trúc và thuật toán dữ liệu khác nhau.

Nếu bạn quan tâm đến cách cấu trúc dữ liệu được triển khai, hãy xem Lago, một thư viện cấu trúc dữ liệu và thuật toán cho JavaScript. Nó vẫn còn khá nhiều WIP nhưng tôi dự định biến nó thành một thư viện có thể được sử dụng như nguồn tham khảo cho việc học các cấu trúc và thuật toán dữ liệu.

Thực hành đến mức nhuần nhuyễn

Tiếp theo, làm quen với các thuật toán và cấu trúc dữ liệu trong ngôn ngữ lập trình bạn đã chọn.

Hãy thực hành và giải các câu hỏi thuật toán bằng ngôn ngữ bạn đã chọn. Trong khi Cracking the Coding Interview là một tài nguyên tốt, tôi thích giải quyết các vấn đề bằng cách tự viết code, cho phép nó chạy, và sẽ nhận được phản hồi ngay lập tức. Song song đó, bạn có thể nhận được sự trợ giúp từ các trang như LeetCode, HackerRank và CodeForces để thực hành các câu hỏi trực tuyến và làm quen với ngôn ngữ. Theo kinh nghiệm của tôi, các câu hỏi của LeetCode là thường được đặt ra trong các cuộc phỏng vấn nhất.

Hãy chắc chắn khoảng thời gian và mức độ phức tạp để viết các thuật toán trong ngôn ngữ bạn đã chọn. Đối với Python, trang này sẽ có ích. Ngoài ra, tìm hiểu về thuật toán phân loại cơ bản được sử dụng trong hàm  sort() của ngôn ngữ và các vấn đề liên quan về thời gian và không gian (trong Python thì đó là Timsort). Sau khi hoàn thành một câu hỏi trên LeetCode, tôi thường thêm những bình luận để nhắc nhở bản thân mình phải có khả năng phân tích thuật toán sau khi đã hoàn thành nó.

Mặt khác, hãy đọc về phong cách lập trình tối được khuyến nghị cho ngôn ngữ của mình. Nếu bạn chọn Python, hãy tham khảo PEP 8 Style Guide. Nếu bạn chọn Java, hãy đọc Google’s Java Style Guide.

Tìm hiểu và làm quen với những lỗi thường mắc phải trong ngôn ngữ. Nếu bạn có thể phát hiện và chỉ ra chúng trong buổi phỏng vấn, bạn sẽ ngay lập tức gây ấn tượng mạnh mẽ với người phỏng vấn, bất kể họ có quen thuộc với ngôn ngữ hay không.

Trong phần sau của bài viết, tôi đề cập đến các loại thuật toán và những câu hỏi hữu ích cho từng chủ đề để thực hành. Một lần nữa, hãy làm khoảng 100 đến 200 câu hỏi trên LeetCode và bạn sẽ ổn thôi.

Tạo Cv online miễn phí cho IT

(Hết phần 1)

TopDev via Medium

  Top 10 câu hỏi phỏng vấn Java thường gặp
  Để lọt vào mắt xanh của Google, Microsoft, Apple, hãy nhớ 4 bí kíp sau!

Top các khóa học Computer Science, Programming, Data Science MIỄN PHÍ cần học ngay!

COMPUTER SCIENCE

PROGRAMMING

DATA SCIENCE

TopDev via Medium

Có thể bạn muốn xem:

  Top những thuật toán machine learning mà bất cứ Data Scientist nào cũng cần phải biết (Phần 1)
  Top các khóa học Computer Science, Programming, Data Science MIỄN PHÍ cần học ngay!
Phân tích dữ liệu xổ số miền Bắc”]

Tại sao không nên lưu trữ data user trên Local Storage?

tai-sao-khong-nen-luu-tru-data-user-tren-local-storage

Tại sao Local Storage không an toàn và bạn không nên dùng nó để lưu trữ data nhạy cảm?

Stick Figure Instructor

Có một vấn đề: hầu hết những thứ xấu về local storage đều không quá quan trọng. Bạn vẫn có thể dùng nó nhưng app sẽ chậm hơn một chút và nhiều phiền toái cho dev. Nhưng vấn đề bảo mật thì khác. Model bảo mật của local storage rất rất quan trọng để biết và nó hoàn toàn ảnh hưởng đến trang web của bạn theo nhiều cách khác nhau.

Còn vấn đề của local storage đó nó không an toàn! Hoàn toàn không. Mọi người đều dùng local storage để store thông tin nhạy cảm như session data, user detail và tất cả những thứ bạn không muốn post công khai trên Facebook.

Local storage không được design như một cơ chế storage an toàn trên browser. Nó được design để store các string đơn giản mà dev có thể dùng để build các app single page phức tạp hơn một chút. Vậy thôi.

Việc làm Data engineer

Việc làm Database

Thứ nguy hiểm nhất trên thế giới là gì? JavaScript!

Hãy thử nghĩ xem: khi bạn store thông tin nhạy cảm lên local storage, bạn cũng đang làm một trong những việc liều lĩnh nhất thế giới là store thông tin lên công cụ tệ nhất mọi thời đại. Nếu bị tấn công cross-site scripting (XSS) thì sao? Tôi sẽ không kể lê thê hết về XSS đâu, nhưng tóm tắt là như thế này:

Nếu một attacker có thể run JavaScript trên wesite của bạn, họ có thể retrive mọi data bạn đã lưu trong local storage và gửi nó đi các domain khác của chúng. Nó có nghĩa là bất kì thứ gì nhạy cảm bạn có đều sẽ được công khai.

Bây giờ, có thể bạn sẽ nghĩ “Vậy thì sao? Website của tôi rất an toàn. Không một ai có thể run JavaScript trên website của tôi được.”

Nếu website của bạn thật sự an toàn và không kẻ nào có thể làm vậy thì căn bản là bạn an toàn nhưng thực tế thì nó rất khó trở nên như vậy. Nếu website của bạn chứa bất kì code JavaScript bên thứ ba nào gồm source ngoài domain:

  • Links đến bootstrap
  • Links đến jQuery
  • Links đến Vue, React, Angular, etc.
  • Links đến ad network code bất kì
  • Links đến Google Analytics
  • Links đến tracking code bất kì

Ví dụ website của bạn có nhúng script tag dưới đây:

<script src="https://awesomejslibrary.com/minified.js"></script>

Trong trưởng hợp này, nếu awesomejslibrary.com bị hack và script minified.js bị thay đổi:

  • Loop mọi data trong local storage
  • Gửi nó qua API được build để thu thập info bị mất

… thì lúc đó bạn tiêu rồi. Lúc này kẻ attack đã có thể xài bất cứ gì bạn có trong local storage và bạn chả bao giờ phát hiện được. Nhưng trên thực tế, chuyện này cũng khá hiếm.

Với nhiều công ty, team marketing trực tiếp quản lý public website dùng các WYSIWYG editors và tools khác nhau. Bạn có chắc là không có phần nào trên site của bạn không dùng JavaScript bên thứ ba không? Dám cá là không.

Lời cảnh báo và giảm risk về bảo mật: làm ơn đừng store cái gì lên local storage cả.

PSA: Đừng store các JSON Web Tokens trên Local Storage

Stick Figure with Stop Sign

Ngoài khuyên bạn tránh xa local storage, tôi nghĩ cũng nên nói về JSON Web Tokens (JWT). Một trong những vấn đề bảo mật tôi thấy là có những người store JWTs (session data) trên local storage. Nhiều người không nhận ra rằng JWTs cũng giống hệt như username và password.

Nếu attacker lấy được bản copy của JWT, chúng có thể gửi request đi trên danh nghĩa của bạn và bạn sẽ không biết được. Hãy xem nó như thông tin credit card của mình hoặc password: đừng lưu trữ nó trên local storage.

Có rất nhiều tutorial, video Youtube, và cả các lớp programming tại trường đại học và coding boot camp dạy cho các dev để store JWT trên local storgae như một cơ chế mặc định. Điều này rất không đúng. Nếu bạn nghe ai đó nói bạn như vậy, tránh xa ngay. Thế thì chẳng lẽ không dùng local storage nữa à? Vậy data user tui muốn lưu thì có cách nào thay thế không man? Mời anh em đọc bài sau.

TopDev

Có thể bạn muốn xem:

  Dùng gì để lưu trữ data thay thế local storage?

7 chiến thuật tuyển dụng IT thành công cho “Ngày hội việc làm IT”

Ngay-hoi-viec-lam-IT

“Theo báo cáo gần nhất của TopDev trong năm 2021 thị trường ngành IT thiếu khoảng 100.000 Developer. Ngày hội việc làm IT là một trong những xu hướng tuyển dụng đang được phổ biến rộng rãi về quy mô lẫn hình thức, một số sự kiện lớn luôn được “dân công nghệ” săn đón như Vietnam Mobile Day, Vietnam Web Summit, TechExpo,… diễn ra thường niên.”

Bạn có từng nghĩ sẽ trở thành nhà tuyển dụng hàng đầu tại ngày hội việc làm IT? Hãy nhớ rằng những ứng viên tài năng luôn nhận được nhiều lời đề nghị hấp dẫn, vì vậy bạn cần sẵn sàng vượt qua các đối thủ bằng mọi cách có thể. Cùng TopDev khám phá 7 chiến thuật tuyển dụng IT hàng đầu sau đây sẽ giúp công ty bạn trở thành đối thủ “nặng ký” với các công ty khác.

Chiến thuật số 1: Thu hút bằng nguồn năng lượng tích cực

Như lời đồn, nếu dân công nghệ khô khan thì ngày hội việc làm IT (Job Fair IT) cũng khó ướt át. Mục đích để tránh tình hình “chiến sự” trở nên căng thẳng anh/chị cần chuẩn bị cho mình những chiến thuật thu hút mang tính khác biệt. Là một HR “thâm niên” trong nghề anh/chị cũng biết rằng trong không gian tuyển dụng có phần ngột ngạt các ứng viên sẽ bị thu hút bởi những trò chơi mang tính trải nghiệm hấp dẫn hoặc một vài thử thách nhỏ nhưng không kém phần thú vị, và đặc biệt phải đánh đúng DNA của Developer với những trò chơi logic, trí tuệ. Với độ khó vừa đủ đô, năng lượng sảng khoái và tinh thần tích cực từ Booth của anh chị sẽ kích thích thêm máu nghề của ứng viên tìm đến và điều anh/chị nhận được đó là CV hoặc những thông tin liên quan mà anh/chị muốn khai thác.

Ngay-hoi-viec-lam-it

Chiến thuật số 2: Rò rỉ thông tin

Bạn có biết, chỉ có khoảng 15.9% ứng viên chủ động tìm kiếm việc, nhưng có đến gần 60% số còn lại là nằm vùng chờ cơ hội, chúng ta hay gọi là “passive candidate”. Nếu các nhà tuyển dụng biết cách tận dụng sức mạnh của các kênh cộng đồng lập trình để “feed” thông tin công ty của bạn tại ngày hội việc làm IT, thì tỷ lệ cao công ty của bạn sẽ được các ứng viên đặc biệt quan tâm và tìm hiểu.

Các trang tuyển dụng IT có thể sử dụng phương tiện truyền thông xã hội như Facebook, Google, LinkedIn, các trang cộng đồng IT như TopDev, Hội dev vui tính, Techtalk.vn, v,v,… và nguồn data ứng viên có sẵn (nếu có) sẽ giúp thông báo tốt về sự hiện diện của công ty bạn. Những thông tin cần thông báo không thể quên đó là vị trí của gian hàng, thời gian diễn ra sự kiện ngày hội việc làm IT, vị trí tuyển dụng và những hoạt động đặc biệt sẽ diễn ra vào ngày hội do chính công ty bạn thực hiện.

Chiến thuật số 3: “Công nghiệp hóa hiện đại hóa” khu vực booth theo chuẩn “Công ty ngành”

Để thể hiện màu sắc công nghệ của công ty mình, bạn có thể ứng dụng những công nghệ không quá phức tạp vào việc thu thập thông tin ứng viên. Ví dụ như thay vì ứng viên phải cầm bút điền thông tin, họ chỉ cần quét QR code và nhập thông tin trực tiếp trên điện thoại của mình, mọi theo tác sẽ trở nên chuyên nghiệp hơn.

Một cách tốt để hấp dẫn ứng viên đến và nộp CV là nhà tuyển dụng có thể sử dụng TV màn hình lớn, để trình chiếu các video về Employer Branding nhằm giúp cho việc giới thiệu công ty được trở nên sinh động hơn và hấp dẫn hơn là những chiếc flyer hay brochure truyền thống. Máy tính bảng sẽ là người bạn đồng hành sáng giá cho các hoạt động mini game hoặc giới thiệu ứng dụng của công ty bạn đến ứng viên tham gia sự kiện.

Ngay-hoi-viec-lam-it

Chiến thuật số 4: Bách phát bách trúng

Đừng tham gia bất kỳ ngày hội việc làm IT nào khi chưa xác định rõ vai trò tuyển dụng của bạn. Mục đích của anh chị không nhất định phải là tuyển dụng trực tiếp tại sự kiện (onsite recruitment), rất nhiều công ty đến với hội chợ việc làm chỉ với mục đích chính là quảng bá thương hiệu và giới thiệu sản phẩm của họ.

Cụ thể hơn ví dụ nếu anh, chị chỉ muốn làm Branding nhận diện thương hiệu thì hình ảnh và thông tin tiêu biểu của công ty phải được hiển thị càng nhiều càng tốt thông qua video, flyer, brochure giúp ứng viên có thể hình dung được phần nào hình ảnh của công ty. Ngoài ra, anh/chị cũng có thể tạo ra những bài viết chuyên về ngành IT trên các kênh cộng đồng sau đó gửi cho các ứng viên của mình thông qua thông tin mà họ cung cấp. Bạn có thể tham khảo thêm một số bài viết về ngành IT tại đây:

  Lập trình viên tại Việt Nam cần ít nhất 5 năm để hiểu rõ một công nghệ!

  Lập trình đâu chỉ có những dòng code

Chiến thuật số 5: “Chọn mặt gửi vàng”

Brand name của công ty bạn sẽ được xây dựng thông qua các HR/Recruitment trực booth vì thế việc ứng cử nhân viên tuyển dụng cần lưu ý đáp ứng đủ các yêu cầu tối thiểu như sự năng động, cởi mở giúp thu hút ứng viên, độ nhạy bén cùng con mắt “nghề” đủ đánh giá khách quan những ứng viên tiêu biểu nhất tại sự kiện. Trong ngày hội việc làm IT nhà tuyển dụng sẽ tiếp xúc trực tiếp với hàng loạt ứng viên vì vậy những hành động giao tiếp nhỏ như nụ cười, sự hướng dẫn cụ thể và cách giúp đỡ nhiệt tình sẽ mang lại cái nhìn tốt từ các Developer.

Ngay-hoi-viec-lam-it

Chiến thuật số 6: “Cho đi và nhận lại”

Nếu anh/chị đã chuẩn bị một khởi đầu hoàn hảo như đã đề cập phía trên thì đừng để kết thúc tẻ nhạt. Sau khi hàng loạt hoạt động chính diễn ra hãy dành riêng một vài điều đặc biệt ở thời gian cuối ngày. Điều này có thể giữ chân được các ứng viên đến hết sự kiện hoặc cũng là lời cảm ơn cho những ứng viên đã đợi ứng tuyển. Anh/chị có thể xem xét về mặt kinh phí để đưa ra những lựa chọn tốt như sách về bí quyết hay trong nghề, áo thun có logo hoặc slogan của công ty, thẻ quà tặng,…nhưng chắc chắn rằng giá trị mang lại tên công ty bạn sẽ được nhắc lại ít nhất một lần nữa khi các ứng viên về đến nhà.

Chiến thuật số 7: Tận dụng điểm mạnh để mang lại chiến thắng

Nghiên cứu của TopDev cho biết có hơn 65% lập trình viên nói rằng mức lương là rất quan trọng với họ vì vậy trước khi tìm một công việc mới họ sẽ luôn tìm hiểu về Background của công ty trước khi nộp CV. Công ty của bạn đã đạt được những thành tựu tiêu biểu nào? Bạn đã từng được gọi tên trong bảng xếp hạng uy tín nào? Tầm nhìn và sứ mệnh của bạn cao cả ra sao? Hãy trưng bày và thể hiện thành tích của mình với các đổi thủ tuyển dụng khác và gây ấn tượng với ứng viên tiềm năng. Càng khẳng định là một thương hiệu uy tín trước các đối thủ thì bạn càng mang lại nhiều kỳ vọng cho ứng viên mong muốn được hợp tác. Tham khảo thêm 03 quy tắc vàng làm Employer Branding tại đây.

Ngày hội việc làm IT sẽ là cơ hội tốt đối với cả nhà tuyển dụng và ứng viên tiềm năng. Nhìn vào tổng thể nếu thực hiện tốt 7 chiến thuật “Xịn” như trên sẽ giúp bạn có một ngày hội việc làm IT thành công như mong đợi. Nhưng để nắm chắc cơ hội thành công bạn cần liệt kê chi tiết hơn và cụ thể hơn những việc phải làm trong từng hạng mục tại hội chợ. Kế hoạch càng bao quát bạn càng dễ dàng kiểm soát và loại bỏ những rủi ro không đáng có xảy ra. Cuối cùng chúc bạn thành công trong ngày hội việc làm IT sắp tới.

  • Có thể bạn quan tâm một sự kiện lớn trong ngành IT sắp diễn ra Vietnam Mobile Day 2019 | Liên hệ đặt Gian hàng tuyển dụng tại Vietnam Mobile Day 2019 – 10,000 lượt tham dự tại ĐÂY.

Máy học – Machine Learning và một vài hạn chế.

Máy học - Machine Learning và một vài hạn chế.

Mặc dù học máy (machine learning) chỉ bắt đầu phát triển vào những năm 1990, nhưng nó đã nhanh chóng trở thành một nhánh con phổ biến nhất và cũng có nhiều thành công nhất của AI, một xu thế được thúc đẩy bởi sự ra đời của phần cứng nhanh hơn và bộ dữ liệu lớn hơn.

Học máy liên quan chặt chẽ đến thống kê toán học, nhưng nó khác với thống kê ở nhiều khía cạnh quan trọng. Không giống như thống kê, học máy có xu hướng xử lý các bộ dữ liệu lớn, phức tạp (như bộ dữ liệu gồm hàng triệu hình ảnh, mỗi bộ gồm hàng chục nghìn pixel) mà phân tích thống kê cổ điển như phân tích Bayes trở nên không thực tế. Do vậy, học máy, và đặc biệt là học sâu, thiếu (có lẽ là rất thiếu) nền tảng toán học và có khuynh hướng kỹ thuật nhiều hơn.

Nó tuân thủ nguyên tắc thực dụng trong đó các ý tưởng thường được kiểm chứng bằng thực nghiệm hơn là được chứng minh một cách chặt trẽ. Trong cuộc sống hàng ngày, hầu hết chúng ta đã quen thuộc với việc mô tả các sự vật, hiện tượng của thế giới bên ngoài qua các khái niệm, các con số, các giác quan…gọi chung là các thuộc tính (feature). Những mô tả đó (tập các thuộc tính) được gọi là các biểu diễn (representation) của sự vật, hiện tượng.

Cùng một sự vật, hiện tượng cũng có nhiều cách biểu diến khác nhau, có biểu diễn rất sáng sủa và cũng có biểu diễn rất mờ mịt; có biểu diễn thuận lợi cho việc này nhưng không dễ xử lý ở công việc khác… Ví dụ chúng ta có thể gắn cho mỗi người một cái tên và một số định danh (duy nhất cho mỗi người). Với “tên”, chúng ta rất dễ nhớ nhưng cũng rất khó khăn khi cần phải xác định một con người cụ thể trong trường hợp trùng tên; ngược lại, “định danh” hoàn toàn xác định chính xác “ai là ai” nhưng gây phiền phức rất lơn khi bắt con người phải nhớ “định danh” của ai đó.

Các biểu diễn cũng có thể chuyển đổi cho nhau để phù hợp với từng nhu cầu cụ thể. Ví dụ chúng ta có thể biểu diễn một hàm số trên miền thời gian và cũng có thể biến đổi chúng về biểu diễn trên miền tần số bằng chuỗi fourier thông qua một ánh xạ mang tên biến đổi fourier. Ánh xạ này cho chúng ta nhìn thấy hình ảnh sáng sủa của một hàm “rối rắm” trong miền thời gian như tổng của các hàm tuần hoàn đơn giản.

Cách nhìn mới cho phép chúng ta áp dụng các công cụ phù hợp để tạo ra các ứng dụng có ý nghĩa hơn (ví dụ trong xử lý tín hiệu). Mục đích của học máy là tìm cách biến đổi các dữ liệu đầu vào thành các dữ liệu đầu ra có ý nghĩa hơn. Nói một cách khác, một mô hình học máy (machine learning model) sẽ ánh xạ dữ liệu từ một không gian biểu diễn vào một không gian biểu diễn khác mà trên đó chúng ta có thể hiểu rõ hơn về dữ liệu ban đầu. Chính vì vậy học máy cũng được gọi là là học biểu diễn (representation learning) hay học thuộc tính (feature learning). Một biểu diễn chính là một cách nhìn vào dữ liệu để biểu diễn hoặc mã hóa chúng.

Chẳng hạn, một hình ảnh màu có thể được mã hóa ở định dạng RGB (đỏ-lục-lam) hoặc ở định dạng HSV (hue-saturation-value): đây là hai cách biểu thị khác nhau của cùng một dữ liệu. Một số công việc có thể khó khăn với một biểu diễn nhưng có thể trở nên dễ dàng với một biểu diễn khác. Ví dụ, việc “chọn tất cả các pixel màu đỏ trong hình ảnh” đơn giản hơn ở định dạng RGB, trong khi đó “làm cho hình ảnh ít bão hòa hơn” lại đơn giản hơn ở định dạng HSV. Tất cả các mô hình học máy đều là việc tìm kiếm các biểu diễn thích hợp cho dữ liệu đầu vào của chúng – biến đổi dữ liệu của bộ dữ liệu làm cho một công việc nào đó trở nên dẽ dàng hơn, chẳng hạn như phân loại các đối tượng.

Quay trở lại ví dụ về phép biến đổi fourier. Phép biến đổi này là thành quả lao động có ý nghĩa vô cùng lớn đồng thời cũng chặt trẽ về mặt lý thuyết của những bộ óc siêu việt và được viết ra thành một công thức tường minh (tức là đã được thuật toán hóa). Tuy nhiên đời không như mơ. Trong thực tế thường không có sẵn (và thậm chí không tồn tại) những món ăn thịnh soạn chờ đợi chúng ta thưởng thức.

Với những trường hợp như vậy, học máy chính là người đấu bếp tạo ra các món ăn (các biểu diễn) từ nguyên liệu ban đầu là dữ liệu. Nói một cách hình tượng, học máy làm thay bộ não con người trong việc tìm kiếm các ánh xạ biến đổi biểu diễn ban đầu của dữ liệu thành dạng biểu diễn có ý nghĩa hơn, trừu tượng và bất biến hơn (ổn định hơn). Điều này cũng cắt nghĩa tại sao nền tảng toán học của học máy còn khá sơ khai. Trong vài năm gần đây, nhiều tác giả đang cố gắng xây dựng nền móng toán học cho học máy khi liên hệ bài toán học máy với các phương pháp giải bài toán ngược (Inverse Problem).

Từ cách nhìn như vậy chúng ta có thể phân biệt hai dạng học máy: học nông (shallow learning) và học sâu (deep learning).Thuật ngữ “deep learning” là cách nói đời thường và mang nhiều sắc thái tiếp thị đôi khi dẫn tới nhầm lẫn. Những người xa lạ với chuyên ngành học máy khi gặp thuật ngữ này thường nghĩ tới việc học một điều gì đó sâu sắc tới ngọn nguồn. Thực chất thuật ngữ “học sâu” ám chỉ việc áp dụng mốt cách tuần tự một chuỗi (lớn hơn 2 và trong thực tế ứng dụng có thể lên tới hàng ngàn) các anh xạ từ không gian biểu diễn này sang một không gian biểu diễn khác, mỗi kết quả (biểu diễn) của ánh xạ ở bước trước sẽ là đầu vào cho ánh xạ ở bước sau để tạo ra một biểu diễn mới mang nhiều ý nghĩa hơn.

Mỗi biểu diễn được goi là một tầng (layer). Chính vì thế học sâu cũng được gọi là “học biểu diễn phân tầng” (layered representations learning) hay “học biểu diễn phân cấp” “hierarchical representations learning”. Trong học sâu, việc học các biểu diễn phân tằng (layered representations) thông thường (hầu hết) được cài đặt dựa trên mô hình của mạng thần kinh (neural networks). Điều này cũng dẫn đến sự hiểu lầm rằng học sâu hoạt động như bộ não hoặc mô phỏng nó. Không giống mạng thần kinh được phát triển một phần nhờ vào cảm hứng từ sự hiểu biết của cúng ta về bộ não, học sâu chỉ là một framework toán học dành cho việc học các biểu diễn từ dữ liệu.

Trái với học sâu, các cách tiếp cận khác trong học máy biến đổi dữ liệu chỉ qua 1 hoặc 2 biểu diễn được gọi là học nông. Những đại diện tiêu biểu của học nông là Decision Trees, Naive Bayes, SVM (Support Vector Machine).

Sự khác biệt giữa học sâu và học nông không chỉ thể hiện về mặt kiến trúc mà còn ở những tính chất đặc trung mà chúng cần có khi áp dụng vào các bài toán khác nhau.
Nếu như với học nông việc xây dựng biểu diễn chủ yếu đặt lên vai con người thông qua “feature engineering” (hay “feature selection”) và đòi hỏi tri thức khá sâu về lĩnh vực ứng dụng thì trái lại học sâu có thể học được các biểu diễn trực tiếp từ dữ liệu mà cần rất ít các tri thức tiên nghiệm (như biến đổi và chuỗi fourier, Bayes…).

Có thể bạn quan tâm: Vị trí machine learning job in vietnam lương cao

Chính vì thế nó cũng được gọi bằng thuật ngữ thể hiện sát với bản chất hơn “feature learning”. Một nhiếp ảnh gia sử dụng công cụ biểu diễn phẳng là các pixel không phải lúc nào cũng ghi nhận được thần thái của nhân vật như bức ký họa nhân vật đó với những nét vẽ (feature) rất đơn giản cảm nhân được của một danh họa. Các “danh họa” như vậy đã được xây dựng trên cơ sở học sâu và có mặt khắp nơi trong các ứng dụng của Google, Facebook, Baidu… tạo nên lợi ích rất lớn.

Một đặc tính quý giá nhất của học sâu dưới quan điểm lý thuyết độ phức tạp tính toán là nó cung cấp cho chúng ta một biểu diễn compact của dữ liệu. Điều này cũng giống như phương pháp Phân tích thành phần chính (Principal Component Analysis – PCA) trong xử lý dữ liệu trên không gian tuyến tính nhẵm giảm số chiều của không gian dùng để biểu diễn dữ liệu – một phương pháp feature selection rất quen thuộc trong các cách tiếp cận học nông. Việc giảm số chiều của biểu diễn có ý nghĩa rất lớn để vượt qua “Lời nguyền của số chiều” (“The curse of dimensionality”) – cách nói ám chỉ hiện tượng bùng nổ tổ hợp trong lưu trữ và tính toán theo số chiều của biểu diễn.

Để thấy rõ hơn sức mạnh biểu diễn của kiến trúc sâu, chúng ta xem xét cài đặt một hàm logic n biến bằng mạch logic. Nếu sử dụng mạch logic nông (như dạng bảng chân lý) đòi hỏi 2**n phần tử tính toán – một việc không khả thi với n đủ lớn -; nhưng với kiến trúc sâu số phần tử tính toán cần thiết giảm đi đáng kể. Lý thuyết cũng chứng minh rằng luôn tồn tại những hàm có thể biểu diễn compact bằng một kiến trúc sâu k tầng nhưng lại phải biểu diễn bằng số lượng hàm mũ các phần tử tính toán khi dùng kiến trúc có k-1 tầng.

Học sâu cũng đồng thời tạo nên tiền đề cho việc biểu diễn phân tán (distributed representation), tính toán phân tán, tính toán song song…khi cho phép lưu trử, xử lý các thuộc tính học được trên nhiều thiết bị tính toán ở nhiều vị trí khác nhau về địa lý. Nó cũng tiềm ấn hy vọng cung cấp một công cụ mới cho việc phát triển transfer learning, multi-task learning – những nhu cầu cơ bản của AI – trong tương lai khi các thuộc tính, các biểu diễn trung gian học được từ một ứng dụng này có thể được sử dụng trong các ứng dụng khác.
Với những ưu điểm kể trên nhiều người lạc quan đã cho rằng “no more features engineering”. Trên thực tế, điều đó không hoàn toàn đúng. Luôn có sự đánh đổi giữa kiến thức tiên nghiệm, lượng dữ liệu đào tạo, khả năng khái quát hóa của các mô hình học được và khó khăn trong việc huấn luyện chúng.

Mặc dù học học máy, đặc biệt là học sâu, đã dẫn đến những thành tựu đáng chú ý trong những năm gần đây, nhưng kỳ vọng về những gì lĩnh vực sẽ có thể đạt được trong thập kỷ tới có xu hướng bị cường điệu hơn nhiều so với những gì có thể. Dưới đây liệt kê một vài rào cản lý thuyết mà học máy chưa thể vượt qua.

“Cho tôi dữ liệu, tôi sẽ sáng tạo lại thế giới”.Đó là sự cường điệu về học máy làm mê hoặc nhiều người và phản ánh sự chuyển hướng từ các phương pháp hướng mô hình trong AI (Model-driven AI, Symbolic AI) khi mục tiêu xây dựng mô hình cho các miền ứng dụng phức tạp tỏ ra không khả thi (ví dụ các hệ chuyên gia – expert systems) sang các phương pháp hướng dữ liệu (Data-driven AI).

Bảo toàn thông tin (conservation of information) là một thuật ngữ mới xuất hiện trong cuốn The Limits of Science xuất bản năm 1984. Trong cuốn sách ngắn gọn, xuất sắc này, tác giả Peter Medawar (nhà sinh vật học, chủ nhân giải Nobel) lý giải bản chất và những hạn chế của việc theo đuổi khoa học. Ba bài tiểu luận của ông liên quan đến một số câu hỏi lớn nhất mà con người biết đến: Khoa học có thể xác định sự tồn tại của Thiên Chúa không? Có một “phương pháp khoa học” nào mà tất cả các bí mật của vũ trụ có thể được khám phá? Peter Medawar đã chỉ ra rằng các hệ thống toán học và tính toán bị giới hạn trong việc tạo ra các hệ quả logic từ một tập hợp tiên đề (hoặc điểm bắt đầu), và do đó không thể tạo ra thông tin mới (mọi hệ quả logic đã tiềm ẩn ngay trong tập các tiên đề) và gọi đó là Định luật bảo toàn thông tin “Law of Conservation of Information”. Định luật này được chúng minh một cách tường minh trong nhiều lĩnh vực AI khác nhau (vd. Phan Đình Diệu, Nguyễn Minh Hải trong logic xác xuất).

Để hiểu ảnh hưởng của Định luật bảo toàn thông tin tới học máy, chúng ta cần thấy bản chất của học máy là tìm ra một biểu diễn tốt nhất giải thích cho mối quan hệ giữa các dữ liệu đầu vào với các dữ liệu đầu ra được kỳ vọng. Đó là một bài toán tối ưu với các ràng buộc chính là dữ liệu. Sau khi hệ thống học máy đã được huấn luyện chúng ta nhận được một mô hình (biểu diễn) giải thích tốt nhất cho dữ liệu. Khi bổ xung một dữ liệu mới tức là chúng ta thêm ràng buộc vào bài toán tối ưu cũ. Ràng buộc mới này có thể “tương thích” với các ràng buộc cũ, hay nói cách khác nó không làm thay đổi miền ràng buộc của bài toán, ta vẫn nhận được biểu diễn cũ. Điều đó có nghĩa dữ liệu mới đã được hệ thống “nhìn thấy” từ góc nhìn của mình (biểu diễn học được). Trường hợp ngược lại, ràng buộc bổ xung sẽ thay đổi miền ràng buộc và vì vậy để giải thích nó, hệ thống phải tìm kiếm một biểu diễn mới – nghiệm tối ưu của bài toán có thêm ràng buộc bổ xung. Một cách hình tượng, biểu diễn cũ không phù hợp để giải thích dữ liệu mới, tức là không “nhìn thấy” dữ liệu mới. Đây cũng là hạn chế chính khiến các hệ thống học máy không thể “ngoại suy” ra những gì chưa được học.

Để khắc phục nhược điểm này của các phương pháp hướng dữ liệu, các nhà nghiên cứu thường đề xuất kết hợp nó với các phương pháp hướng mô hình. “No Free Lunch Theorem” và “Ugly Ducking Theorem”. Đây là một “nút thắt cổ chai” khi cần trả lời câu hỏi “Thuật toán nào là tốt nhất cho học máy?”.

Để đánh giá hiệu quả của thuật toán chúng ta sử dụng tập dữ liệu kiểm tra (testing set).
Trong trường hợp tập dữ liệu kiểm tra hoàn toàn độc lập với tập dữ liệu huấn luyện (training set) chúng ta bị khống chế bới Định luật bảo toàn thông tin và vì vậy mọi thuật toán đều tồi tệ. Khi tập huấn luyện rất lớn và hai tập hợp chồng lấn lên nhau, các hệ thống học máy trở thành những học trò “học vẹt” để trả thi (kiểm tra mức độ thuộc bài) và không có khả năng trừu tượng hóa.

Định lý “No Free Lunch” chỉ ra rằng không tồn tại một thuật toán vượt trội thuật toán khác trong mọi tập dữ liệu có được. Hay nói cách khác, sai số trung bình trên mọi tập dữ liệu là như nhau đối với mọi thuật toán. Một thuật toán “tốt hơn” trong ứng dụng này có thể “tồi tệ” đối với ứng dụng khác. Điều này cản trở lớn tới việc scalling up các thuật toán học máy.
Tương tụ như “No Free Lunch Theorem”, định lý “Ugly Ducking Theorem” cũng khẳng định rằng không có tập thuộc tính (biểu diến) nào là “tốt nhất” nếu không xét đến các giả thiết bổ xung. Điều này cũng góp phần phủ định tư duy “no more features engineering” đã nhắc tới ở trên.

Để thay lời kết của bài này tôi xin trích dẫn ý kiến của Margaretta Colangelo – người có hơn 30 năm kinh nghiệm trong công nghệ phần mềm tại thung lũng Silicon với hơn 60 công bố giá trị về Deep Tech, AI và y sinh học hiện đại đồng thời tham gia điều hành nhiều tổ chức nghiên cứu trên thế giới – khi bà nhắc chúng ta chớ nên quên lãng giá trị của dữ liệu nhỏ cũng như khả năng trừu tượng hóa kỳ diệu của con người so với máy móc và kêu gọi nghiên cứu phát triển các phương pháp AI đòi hỏi ít dữ liệu hơn:

“Tất cả mọi thứ đều là dữ liệu nhỏ trước khi chúng ta có dữ liệu lớn. Những khám phá khoa học của thế kỷ 19 và 20 đều được thực hiện bằng cách sử dụng dữ liệu nhỏ. Darwin đã sử dụng dữ liệu nhỏ. Các nhà vật lý đã thực hiện tất cả các tính toán bằng tay, do đó họ chỉ sử dụng dữ liệu nhỏ. Tuy nhiên, họ đã khám phá ra những quy luật đẹp nhất và cơ bản nhất của tự nhiên. Hơn nữa, họ nén chúng thành các quy tắc đơn giản dưới dạng các phương trình thanh lịch. Einstein là nhà vô địch điều này với E = mc². Mặc dù người ta đã ước tính rằng có lẽ 60% đến 65% trong số 100 phát minh lớn nhất của thời đại chúng ta thực sự dựa trên dữ liệu nhỏ, các phát triển AI hiện tại dường như quá tập trung vào dữ liệu lớn mà quên đi giá trị của việc quan sát các mẫu nhỏ”

Có thể bạn quan tâm: Vị trí machine learning job in vietnam lương cao

TopDev via Minh Hai Nguyen

  Top 20 API trong AI và Machine Learning bạn nên biết
  Tổng hợp tài liệu tự học lập trình Python "from Zero to Hero"

5 ví dụ chứng minh dân coder là những anh chàng vui tính nhất thế giới

Những dòng code khô khan vẫn có thể ẩn chứa những trò đùa mỉa mai rất thâm sâu của giới lập trình.

Dịch vụ lưu trữ, chia sẻ code GitHub có tới 35 triệu dự án mã nguồn mở. Rất nhiều trong số đó là các gói sản phẩm phức tạp được cộng đồng lập trình viên và các doanh nghiệp trên thế giới tin dùng. Một số khác lại là các thư viện có mục đích đơn giản, dễ hiểu để tiết kiệm thời gian cho các coder khác.

Một số đơn giản chỉ là những trò đùa.

Những câu đùa dựa trên các dòng code có lẽ sẽ là quá khô khan với phần đông độc giả công nghệ. Đừng lo lắng, chúng tôi sẽ giải thích cho bạn về một số dự án (project) vui nhộn nhất trên GitHub.

1. TrumpScript: Một ngôn ngữ lập trình dựa trên tấm gương Donald Trump

Đây là tác phẩm do 4 sinh viên Đại học Rice tạo ra trong một cuộc thi hack. Theo mô tả, các tác giả của TrumpScript “phát hiện ra rằng không có ngôn ngữ nào trong số các ngôn ngữ lập trình hiện tại sẽ nhận được sự tán thưởng từ mái tóc vàng của Trump”.Với khoảng 1000 dòng code, TrumpScript là một “giả ngôn ngữ” với tính năng khá hạn chế dù vẫn có thể được sử dụng để làm một số tác vụ cơ bản. Sau đây là một số tính năng của TrumpScript:

– TrumpScript chỉ cho phép sử dụng các con số lớn hơn 1 triệu, vì “các thứ nhỏ nhặt không có giá trị”. Khi sử dụng các con số giá trị dưới 1 triệu, coder sẽ nhận được thông báo lỗi có nội dung là một tuyên bố nổi tiếng từ ngài Trump: “Tôi rất giàu. Một phần vẻ đẹp của tôi là tôi rất giàu“.

– TrumpScript không cho phép sử dụng phân số hoặc số thập phân mà chỉ chấp nhận các số nguyên, vì “Nước Mỹ sẽ không bao giờ làm thứ gì đó nửa chừng“.

– Khi chạy trên TrumpScript, bạn sẽ nhận được một thông báo lỗi khác từ ngài Trump: “Windows? Vấn đề lớn nhất của đất nước này là PC“.

– Tất cả mọi ứng dụng viết bằng TrumpScript phải kết thúc bằng câu “Nước Mỹ thật vĩ đại“.

Dĩ nhiên là với các tính năng này, TrumpScript sẽ là một ngôn ngữ gần như vô dụng. Trong phần lớn các trường hợp TrumpScript cũng không hiện thông báo lỗi, vì theo các tác giả, “Trump không thích nói về thất bại của mình”.

2. Is-thirteen: Kiểm tra xem một số nào đó có phải là 13 hay không

Bạn có thể kiểm tra xem một số nào đó có phải là số 13 hay không bằng cách viết ra những đoạn code tương tự như dưới đây:

Kể cả bạn không biết gì về code thì bạn vẫn có thể hiểu được 4 dòng code quá ư đơn giản này. Đó chính là trò đùa thâm sâu của các tác giả is-thirteen: gói phần mềm này mất tới hàng trăm dòng code chỉ để thực hiện tác vụ của 4 dòng code vô dụng. is-thirteen cũng có tới 92 người tham gia và thậm chí có cả chính sách chỉnh sửa/đóng góp code.

Is-thirteen được tạo ra để mỉa mai các gói phần mềm có công dụng quá đơn giản và thừa thãi. Ví dụ, một project trong đời thực sẽ kiểm tra xem liệu một số có lớn hơn 0 hay không. Triết lý chế tạo các gói phần mềm quá vụn vặt, có tính năng quá giới hạn như thế này đã từng bị chỉ trích kịch liệt vào năm ngoái, khi một hacker mũ trắng xóa đi 11 dòng code được anh này đóng góp cho javaScript.

Các lập trình viên khác cũng hưởng ứng trò đùa này rất tích cực. Trên GitHub, is-thirteen có hẳn một mục thảo luận với những đầu mục như:

– Thêm tính năng hỗ trợ XIII

– Bỏ hỗ trợ cho Thứ sáu Ngày 13

– Thêm tính năng hỗ trợ bộ phim “Thirteen”.

– Thành lập Ủy ban Chiến lược Công nghệ.

– Hỗ trợ máy học.

Nếu bạn muốn sử dụng (và phụ thuộc) vào các gói mã nguồn như is-thirteen, hãy lưu ý tới cảnh báo của các tác giả: “Hãy đọc mã nguồn vì chúng tôi thay đổi rất nhanh và làm hỏng nhiều thứ”.

  Học lập trình thế nào để không thất nghiệp?

3. ComcastifyJS: Giảm tốc độ tải ảnh

Bất bình trước chất lượng dịch vụ và chăm sóc khách hàng ngày càng đi xuống của nhà mạng ComCast, các lập trình viên làm việc cho tờ báo biếm họa The Onion đã tạo ra giải pháp ComcastifyJS để giải quyết vấn đề “Đôi khi ảnh web load quá nhanh”.

“Với tất cả những cái thứ Internet này, đôi khi bạn muốn tận hưởng cảm giác giật gân của những trang web ì ạch. Hãy cho phép người dùng của bạn được tận hưởng một phần của tương lai bằng cách tải trang web thật chậm nhờ có ComcastifyJS”.

Trang demo của ComcastifyJS sẽ trình bày tính năng đã quá quen thuộc với người dùng Comcast: ảnh tải siêu chậm. Một lập trình viên vui tính đề xuất Comcastify tạo ra một gói dịch vụ trả phí cao cấp để người dùng có thể tận hưởng trải nghiệm tải ảnh… chậm hơn nữa. Một người khác biến Comcastify thành extension cho Chrome.

Nếu có thời gian, bạn có thể ghé qua trang GitHub của The Onion để tìm hiểu thêm về các project buồn cười khác như fartscroll.js, một plugin web có khả năng tạo ra tiếng “xì hơi” mỗi lần bạn cuộn trang trên web.

4. Thay thế Lorem Ipsum bằng lyrics của Justin Bieber.

Dù có code hay không thì chắc hẳn bạn cũng đã từng nhìn thấy cụm “Lorem Ipsum” khi đi tìm biểu mẫu web, blog hay Word, Excel, PowerPoint. “Lorem Ipsum” thực chất là một đoạn triết học khó hiểu viết bằng tiếng Latin được sử dụng trong nhiều thế kỷ, giúp cho các nhà thiết kế có thể tạo biểu mẫu dàn chữmà không cần lo lắng người dùng sẽ bị phân tâm như khi đọc nội dung có nghĩa.

Nhưng tại sao lại trình diễn giao diện tuyệt đẹp của bạn bằng một cụm chữ Latin cổ. Trong mục awesome-ipsum trên GitHub, bạn có thể sử dụng rất nhiều cụm từ (có vẻ) vô nghĩa khác thay thế, ví dụ như:

– Pasta Ipsum: Bao gồm rất nhiều loại Mỳ Ý khác nhau. Có tùy chọn thêm từ… chửi thề một cách ngẫu nhiên.

– Hipster Ipsum: Thêm vào những từ ưa thích của giới hipster.

– Corporate Ipsum: Thêm vào những cụm từ “đao to búa lớn” của giới lãnh đạo doanh nghiệp.

– Justin Bieber Ipsum: Thêm vào những câu nói kinh điển từ Justin Bieber.

5. Những thư viện JavaScript hoàn toàn vô dụng

Chịu trách nhiệm quản lý các tác vụ “động” (ví dụ như tải thêm các câu status cũ khi bạn cuộn tới cuối trang Facebook thay vì tải lại toàn bộ), JavaScript là một trong 3 phần quan trọng nhất của trải nghiệm web. Và cũng giống như các ngôn ngữ lập trình khác, JavaScript sở hữu nhiều thư viện để mỗi lập trình viên có thể tái sử dụng các tính năng đã được một lập trình viên khác tạo ra.

Nhưng vấn đề với các thư viện code là ở chỗ đôi khi chúng không nên tồn tại: rất nhiều người đã và đang tạo ra những thư viện nhằm cung cấp các tính năng đã có sẵn từ các bộ thư viện tiêu chuẩn. Để mỉa mai tình trạng này, một số coder đã tạo ra các thư viện JS vui nhộn như:

– vapor.js: thư viện không có một dòng code nào, được mô tả là “Thư viện JavaScript Nhỏ nhất và Nhanh nhất”.

– semicolon.js: “Phiên bản an toàn và ổn định hơn của vapor.js”. Nội dung của semicolon.js là một dấu chấm phẩy (ký tự dùng để kết thúc câu lệnh).

– vanilla.js: biên dịch JavaScript thành… JavaScript. Thư viện vô dụng tuyệt đối này đã từng khiến một lập trình viên kém may mắn mắc lừa và lên Stack Overflow đặt câu hỏi: “Tại sao vanilla.js lại được coi là một framework?”.

TopDev Via GenK

  Cách mà một dòng code đã thay đổi cuộc đời tôi!
  Lập trình đâu chỉ có những dòng code

Flutter Vs. React Native: So sánh chi tiết về những điểm tương đồng và ưu việt

flutter-vs-react-native-so-sanh-chi-tiet-ve-nhung-diem-tuong-dong-va-uu-viet

Tác giả: SPEC INDIA

Cách đây vài ngày, Google đã cho ra mắt Google Hummingbird, một platform phát triển ứng dụng mới của Google và phát hành phiên bản ổn định hơn cho Flutter, một SDK phát triển mobile app nguồn mở của Google.

Những điểm đáng chú ý của Flutter

Flutter là SDK nguồn mở của Google dùng để tạo các ứng dụng chất lượng cao cho Android và iOS bằng cách sử dụng một codebase.

Ngày 4 tháng 12, Google đã tổ chức sự kiện Flutter Live để chào mừng SDK mobile mới, Flutter và phiên bản ổn định đầu tiên của nó.

Họ cũng công bố project Google Hummingbird cho phép các developer chỉ cần build một ứng dụng một lần và sau đó có thể chạy nó ở bất kỳ nơi nào.

Thời gian gần đây, sự phổ biến của các mobile app dường như không có dấu hiệu giảm nhiệt. Mỗi ngày đều có rất nhiều app được develop và deploy trên các app store. Không chỉ native app mà cross-platform app và hybrid app cũng được các app developer và chuyên gia kinh doanh tập trung phát triển.

Bên cạnh các ưu và nhược điểm của mình thì mỗi framework đều có kiến trúc độc đáo để build app. Trong khi các native app cung cấp trải nghiệm người dùng vượt trội, thì cross-platform và hybrid được thiết kế để tiết kiệm thời gian và chi phí cũng như cung cấp time-to-market nhanh hơn.

Trong bài viết này, chúng ta sẽ thảo luận về sự tương đồng và khác biệt giữa hai tool phát triển cross-platform app là React Native và Flutter.

Có thể bạn quan tâm

  Flutter khác biệt gì so với những công nghệ đương thời?

Flutter đang dần được nhiều người ưa thích: Tại sao bạn nên chú ý đến nó?

Như đã được đề cập ở trên, SDK nguồn mở và miễn phí này được hỗ trợ bởi Google và được dùng để phát triển các ứng dụng cho Android và iOS.

Nó dựa trên ngôn ngữ Dart và cung cấp thư viện đồ họa hấp dẫn. Các feature chính của platform này là:

  • SDK cho platform chính xác và chi tiết
  • Các widget được thiết kế chi tiết, chính xác
  • Môi trường hoàn toàn tùy chỉnh
  • Native Performance
  • Feature Stateful Hot Reload để phát triển app nhanh hơn

Tháng 05/2017, Google giới thiệu Flutter tới cộng đồng, sau đó vào ngày 04/12/2018, phiên bản ổn định hơn của Flutter được phát hành. Bên cạnh đó, Flutter có thể được sử dụng để tạo các ứng dụng cho Google Fuchsia, một hệ điều hành dựa trên khả năng của Google.

Feature Stateful Hot Reload của Flutter: Các developer sẽ thích

Feature này cho phép các developer build các UI một cách nhanh chóng và dễ dàng hơn. Nó đưa code được update vào Dart Virtual Machine, cho phép phản ánh nhanh các thay đổi và fix bug.

Ai đang sử dụng Flutter?

  • Alibaba, gã khổng lồ eCommerce lớn nhất thế giới, đã sử dụng Flutter để tạo ra trải nghiệm tuyệt vời trên app Xianyu của họ
  • Reflecting, một app tạp chí hấp dẫn cũng được build với Flutter
  • Hamilton Musical, app chính thức của Broadway Music được tạo bởi Flutter
  • Google Greentea, app quản lý khách hàng nội bộ sử dụng Flutter trong môi trường phát triển của nó
  • JD Finance, một công ty FinTech hàng đầu sử dụng Flutter
  • App Abbey Road Studios được build với Flutter

Mặt khác, React Native cũng đang phát triển mạnh mẽ với hiệu suất ứng dụng vượt trội trên cả hai platform, iOS và Android. Tính tới thời điểm hiện tại, React Native là một trong những project nguồn mở hàng đầu trên GitHub.

Facebook chủ yếu sử dụng React Native cho những project quan trọng của mình.

Oculus Go VR Headset cùng với mobile app đi cùng cũng được build hoàn chỉnh với React Native.

Facebook và React Native Community đang cải tiến framework tái kiến trúc quy mô lớn để làm cho nó linh hoạt và tốt hơn.

Mặc dù Flutter và React Native là hai framework khác nhau nhưng chúng cũng có một số điểm chung.

Điểm tương đồng giữa Flutter và React Native

Cả hai đều được thiết kế để phát triển cross-platform app

React Native và Flutter đều cung cấp hiệu suất ứng dụng vượt trội, nhanh chóng và chất lượng cao trên nhiều platform bao gồm Android, iOS và UWP.

(Lưu ý: Flutter hỗ trợ platform Android và iOS)

Cả hai framework được hỗ trợ bởi các cộng đồng công nghệ khổng lồ

React Native được cung cấp bởi Facebook còn Flutter là SDK nguồn mở của Google để phát triển mobile app. Cả hai đều có cộng đồng các developer mạnh mẽ

Nguồn mở, miễn phí và nhanh chóng

React Native và Flutter là các SDK nguồn mở và miễn phí cho phép các developer tạo ra các app tuyệt vời một cách nhanh chóng dựa vào native performance của chúng.

Documentation chi tiết và luôn được cập nhật

Các cộng đồng của cả hai framework này luôn nỗ lực hết sức để liên tục cập nhập documentation mới nhất với các tài liệu tham khảo API và tài nguyên toàn diện.

Hỗ trợ UI và Native Experience tuyệt vời

React Native sử dụng các yếu tố xây dựng UI cơ bản trong Android / iOS để mang lại native experience. Flutter cũng sử dụng các widget để cung cấp native experience đáng chú ý trên platform Android và iOS.

Hot reloading và sửa đổi nhanh

React Native hỗ trợ “Hot reloading” cho phép đồng thời chạy code mới và giữ trạng thái ứng dụng, thay vì phải recompile. Tính năng này làm cho sự phát triển nhanh hơn, tức thì và hiệu quả.

Flutter cũng không hề kém cạnh. “Stateful Hot Reloading” của nó hỗ trợ phản ánh các thay đổi ngay lập tức mà không cần restart hoặc trong trường hợp mất trạng thái ứng dụng.

Chúng ta đã điểm qua sự giống nhau của React Native và Flutter, bây giờ hãy cùng xem qua những khác biệt của chúng trong process, flow, và feature.

Tham khảo việc làm React Native lương cao cho bạn

Flutter vs. React Native: Khám phá sự khác biệt

Điểm khác biệt chính nằm ở ngôn ngữ lập trình

Flutter sử dụng Dart.

React Native cho phép bạn phát triển một app bằng JavaScript. Tôi không cần giới thiệu thêm gì nữa về Javascript vì nó đã quá phổ biến bởi code dành cho mobile, web, hoặc server-specific rồi.

Mặt khác, Dart khá mới đối với các developer. Nó sử dụng các feature hiện đại của một số ngôn ngữ để code các native app đẹp. Trong khi đó Javascript không có bất kỳ component và styling nào, cũng như không có sự tách biệt của các template, style và data. Dart rất dễ sử dụng cho những người có kinh nghiệm phát triển app bằng các ngôn ngữ OOP như C ++ và Java.

Tính ổn định và tính linh hoạt

Xét về tính ổn định, không có sự khác biệt đáng kể nào vì cả hai đều được quản lý bởi các cộng đồng công nghệ mạnh mẽ.

Xét về tính linh hoạt và tùy biến, Flutter cung cấp một set widget tùy chỉnh phong phú để build những trải nghiệm hấp dẫn. Mặt khác, React Native cung cấp trải nghiệm người dùng liền mạch thông qua giao tiếp trực tiếp với các native platform.

Flutter đang cố gắng để có chỗ đứng trên thị trường do phát hành bản ổn định gần đây, còn React Native vẫn đang tận hưởng vị trí đầu tiên trong danh sách các tool phát triển ứng dụng cross-platform trên thị trường.

Thời gian phát triển của một app

Các công ty tận dụng cross-platform để tiết kiệm thời gian code app bằng nhiều ngôn ngữ.

Bên cạnh đó, cả React Native và Flutter đều cam kết cung cấp time-to-market cho app nhanh hơn. Bạn có thể sử dụng library của bên thứ ba và các component sẵn-sàng-để-sử-dụng để build một app. Một loạt các widget tùy chỉnh và chất lượng cao giúp build một app trong thời gian ngắn hơn so với phát triển native app.

Hiệu suất: Ai thắng?

Flutter chắc chắn chiến thắng ở phần này nhờ vào sự đơn giản của nó.

Tuy nhiên, React Native lại nổi tiếng với việc truyền tải trải nghiệm người dùng tuyệt vời trên cả hai platform. Flutter có thêm lợi thế là sử dụng lại code trong khi React Native ít phù hợp hơn do kiến ​​trúc của nó. Một lợi thế khác của Flutter khi so với layer JavaScript là giúp giao tiếp với các native component dễ dàng hơn.

Cả hai đều là sự lựa chọn đáng tin cậy nhưng Flutter có lợi thế cạnh tranh hơn vì tính đơn giản và Dart platform của nó.

IDE và dễ code

Flutter còn khá mới và được hỗ trợ bởi Android Studio / IntelliJ, Visual Studio Code hiện tại. Còn React Native đã có 3 năm tuổi kể từ khi ra mắt, nó được hỗ trợ tốt bởi hầu hết các IDE hàng đầu.

React Native cung cấp curve dễ học do sử dụng JavaScript. Flutter thì đòi hỏi phải học Dart để tạo ra một app. Tuy nhiên, Dart là một điểm cộng cho các C ++ và Java developer.

Flutter vs React Native – So sánh nhanh

Cả hai framework đều có những ưu và nhược điểm riêng của mình.

Hãy cùng khám phá thêm một số ưu điểm và hạn chế của Flutter

Ưu điểm

  • Documentation sạch sẽ, rõ ràng và trơn tru
  • Sự hỗ trợ từ Google và một cộng đồng mạnh mẽ
  • Tốc độ phát triển nhanh hơn
  • Native app performance tuyệt vời
  • Một loạt các UI component dễ biểu đạt và linh hoạt
  • Stateful Hot Reloading cho sự thực hiện thay đổi nhanh hơn
  • Khả năng truy cập native SDK và các feature của chúng
  • Cách tiếp cận coding hiện đại, nâng cao và linh hoạt
  • API hỗ trợ các hiệu ứng, animation và gesture 2D

Nhược điểm

  • Mặc dù Dart là một ngôn ngữ lập trình dễ sử dụng, nhưng Flutter yêu cầu phải học Dart
  • Khó khăn trong việc styling cho các component
  • Quản lý vòng đời phức tạp hơn so với React Native
  • Vì chỉ mới ra mắt được một năm , nó không trưởng thành như React Native

Chúng ta không thể xác định được cái nào là tốt nhất vì phụ thuộc vào nhiều yếu tố như requirement, budget, feature và các developer. Tuy nhiên, bạn có thể thích cái nào cũng được và dùng cho project phát triển app cross-platform tiếp theo vì cả 2 đều là tool nhất quán, đơn giản và tốt

Kết luận

Chọn Flutter nếu bạn muốn cross-platform, UI hấp dẫn, native performance tuyệt vời, time-to-market nhanh hơn và tận dụng lợi thế cạnh tranh của Dart trong môi trường lập trình của bạn.

Chọn React Native nếu bạn muốn tận dụng sự hỗ trợ từ cộng đồng mạnh mẽ và trưởng thành hơn, native app performance và sự phổ biến của JavaScript trong việc phát triển các cross-platform app.

Hy vọng bạn thích đọc bài viết này.

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

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

Hướng dẫn bắt đầu GraphQL với Node.js (Phần 1)

Hướng dẫn bắt đầu GraphQL với Node.js (Phần 1)

Hầu hết chúng ta có thể rất quen thuộc với việc tạo REST API. GraphQL là một query language được tạo ra bởi Facebook với mục đích xây dựng các ứng dụng cho khách hàng dựa trên cú pháp trực quan và linh hoạt để mô tả các yêu cầu và tương tác dữ liệu. GraphQL được thiết kế để giải quyết một trong những nhược điểm lớn nhất của các API giống như REST. Một dịch vụ GraphQL được tạo ra bằng cách định nghĩa các loại và các trường, sau đó cung cấp các chức năng cho mỗi trường trên mỗi loại.

Một khi dịch vụ GraphQL đang chạy (thường là tại một URL trên web), nó có thể được gửi các truy vấn GraphQL để xác nhận và thực hiện. Truy vấn đã nhận được kiểm tra lần đầu để đảm bảo nó chỉ đề cập đến các loại và trường được xác định, sau đó chạy các hàm để tạo ra kết quả.

#Tính năng của GraphQL 

  • Hierarchical – các truy vấn chính xác như dữ liệu mà chúng trả về.
  • Các truy vấn do khách hàng chỉ định – khách hàng có quyền tự do quyết định lấy gì từ máy chủ,
  • Strongly typed – bạn có thể xác thực một truy vấn theo cú pháp và trong hệ thống kiểu GraphQL trước khi thi hành. Điều này cũng giúp thúc đẩy các công cụ mạnh mẽ để cải thiện trải nghiệm phát triển, như GraphiQL.
  • Introspective – bạn có thể truy vấn hệ thống sử dụng cú pháp GraphQL. Điều này rất tốt cho việc phân tích cú pháp dữ liệu đến vào các giao diện strongly-typed và không phải  phân tích cú pháp và chuyển đổi bằng tay JSON thành các đối tượng.

#Tại sao phải dùng GraphQL

Một trong những thách thức chính đối với các REST call truyền thống là không có khả năng khách hàng yêu cầu một bộ dữ liệu tùy chỉnh (giới hạn hoặc mở rộng). Trong hầu hết các trường hợp, một khi khách hàng yêu cầu thông tin từ máy chủ, nó sẽ nhận tất cả hoặc không có bất kì trường nào.

Một khó khăn khác là làm việc và duy trì nhiều điểm cuối. Khi nền tảng phát triển, do đó số lượng sẽ tăng lên. Vì vậy, khách hàng thường cần phải yêu cầu dữ liệu từ các endpoint khác nhau. GraphQL API được tổ chức theo các loại và trường, chứ không phải endpoint. Bạn có thể truy cập đầy đủ các tính năng của dữ liệu từ một điểm cuối.

Khi xây dựng một máy chủ GraphQL, chỉ cần có một URL cho tất cả dữ liệu tìm nạp và biến đổi. Do đó, khách hàng có thể yêu cầu một bộ dữ liệu bằng cách gửi một chuỗi truy vấn, mô tả những gì họ muốn, đến một máy chủ.

#Cài đặt

Chúng ta sẽ bắt đầu với một cấu trúc tệp đơn giản và một đoạn code mẫu đơn giản. Để làm theo hướng dẫn này, bạn tạo một thư mục GraphQLvà bên trong thư mục khởi tạo một dự án npm sử dụng npm init -y. Sau đó, tạo tệp server.js mà sẽ là tệp chính. Đối với code hoàn chỉnh, sao chép bằng cách sử dụng các hướng dẫn trong kho github đính kèm.

Chúng tôi sẽ cài đặt các package cần thiết.

npm i graphql express express-graphql -S   #Install required packages

Chúng tôi sẽ thiết lập một máy chủ đơn giản dùng Express và Express-Graphql, một máy chủ trung gian HTTP. Đừng lo lắng về ý nghĩa của code bởi vì chúng ta sẽ khám phá từng bước một trong các bước tiếp theo khi thêm nội dung khác.

var express = require('express');
var graphqlHTTP = require('express-graphql');
var { buildSchema } = require('graphql');

// Initialize a GraphQL schema
var schema = buildSchema(`
  type Query {
    hello: String
  }
`);

// Root resolver
var root = { 
  hello: () => 'Hello world!'
};

// Create an express server and a GraphQL endpoint
var app = express();
app.use('/graphql', graphqlHTTP({
  schema: schema,  // Must be provided
  rootValue: root,
  graphiql: true,  // Enable GraphiQL when server endpoint is accessed in browser
}));
app.listen(4000, () => console.log('Now browse to localhost:4000/graphql'));

#Concepts

Cho đến nay chúng ta đã khám phá một số tính năng và lợi thế của GraphQL. Chúng ta sẽ nghiên cứu các thuật ngữ khác nhau và triển khai một số tính năng kỹ thuật trong GraphQL. Chúng tôi sẽ sử dụng một máy chủ Express đơn giản để phân tích các feature.

  Hướng dẫn bắt đầu GraphQL với Node.js (Phần 1)
Xây dựng forum bằng GraphQL, React, Apollo và Prisma – Part 1 :Application Introduction and Technologies Overview”]

Schema

Trong GraphQL, Schema quản lý các truy vấn và đột biến, xác định những gì được phép thực hiện trong máy chủ GraphQL. Một giản đồ định nghĩa một hệ thống kiểu của GraphQL API. Nó mô tả tập hợp các dữ liệu có thể (object, field, relationship, mọi thứ) mà khách hàng có thể truy cập. Cuộc gọi từ máy khách được xác nhận và thực hiện đối với lược đồ. Một khách hàng có thể tìm thông tin về schema thông qua quá trình phân tích. Một schema nằm trên máy chủ GraphQL API.

Ngôn ngữ GraphQL Interface Definition (IDL) hoặc Ngôn ngữ Schema Definition (SDL) là cách ngắn gọn nhất để chỉ định GraphQL Schema. Các component cơ bản nhất của GraphQL schema là các loại đối tượng, chỉ đại diện cho một loại đối tượng mà bạn có thể lấy ra từ dịch vụ của mình và những trường nào nó có. Trong ngôn ngữ GraphQL schema, chúng ta có thể đại diện cho nó như sau:

type User {
  id: ID!
  name: String!
  age: Int
}

Trong đoạn trên, chúng ta đang sử dụng hàm buildSchema để xây dựng một đối tượng Schema từ ngôn ngữ GraphQL schema.

var schema = buildSchema(`
  type Query {
    hello: String
  }
`);

Xây dựng các Type

Bên trong buildSchema, chúng ta có thể định nghĩa các kiểu khác nhau. Bạn có thể nhận thấy trong hầu hết các trường hợp kiểu Query {...} và type Mutation {...}type Query {...} là một đối tượng đang nắm giữ các chức năng sẽ được ánh xạ tới các truy vấn GraphQL; được sử dụng để lấy dữ liệu (tương đương với GET trong REST) trong khi type Mutation {...} chứa các chức năng sẽ được ánh xạ tới mutaions; được sử dụng để tạo, cập nhật hoặc xóa dữ liệu (tương đương với POST, UPDATE và DELETE trong REST).

Chúng tôi sẽ làm cho chema phức tạp hơn bằng cách thêm một số loại hợp lý. Ví dụ: chúng tôi muốn trả lại user và một mảng users có các thuộc tính   idname ,age và gender .

var schema = buildSchema(`
  type Query {
    user(id: Int!): Person
    users(gender: String): [Person]
  },
  type Person {
    id: Int
    name: String
    age: Int
    gender: String  
  }
`);

Bạn có thể thấy một số cú pháp thú vị ở trên, [Person] có nghĩa là trả về một mảng kiểu Person trong khi dấu chấm than trong user(id: Int!) Có nghĩa là id  phải được cung cấp. truy vấn users lấy một biến giới tính tùy chọn.

Resolver

Resolver có trách nhiệm lập bản đồ hoạt động để thực hiện function. Bên trong type Query, chúng tôi có một hoạt động được gọi là users. Chúng tôi xác định hoạt động này đến một function có cùng tên tại root. Chúng tôi cũng sẽ tạo ra một số người dùng giả cho function này.

...
var users = [  // Dummy data
  {
    id: 1,
    name: 'Brian',
    age: '21',
    gender: 'M'
  },
  {
    id:2,
    name: 'Kim',
    age: '22',
    gender: 'M'
  },
  {
    id:3,
    name: 'Joseph',
    age: '23',
    gender: 'M'
  },
  {
    id:3,
    name: 'Faith',
    age: '23',
    gender: 'F'
  },
  {
    id:5,
    name: 'Joy',
    age: '25',
    gender: 'F'
  }
];

var getUser = function(args) { ... }  // Return a single user
var retrieveUsers = function(args) { ... } // Return  a list of users
...
var root = { 
  user: getUser,   // Resolver function to return user with specific id
  users: retrieveUsers
};

Để làm cho code trở nên dễ đọc hơn, chúng ta sẽ tạo các function riêng biệt thay vì xếp tất cả mọi thứ vào bộ root resolver. Cả hai function này lấy một tham số tùy chọn args mang các biến từ truy vấn của khách hàng. Hãy cung cấp một thực hiện cho các resolver và thử nghiệm các function của chúng.

...
var getUser = function(args) { // return a single user based on id
  var userID = args.id;
  return users.filter(user => {
    return user.id == userID;
  })[0];
}

var retrieveUsers = function(args) { // Return a list of users. Takes an optional gender parameter
  if(args.gender) {
    var gender = args.gender;
    return users.filter(user => user.gender === gender);
  } else {
    return users;
  }
}
...

Query

query getSingleUser {
    user {
        name
        age
        gender
    }
}

Output

Trong biểu đồ ở trên, chúng tôi đang sử dụng một hoạt động getSingleUser để có được một người dùng duy nhất với tên, giới tính và độ tuổi. Chúng tôi có thể tùy ý chỉ định rằng chúng tôi cần tên của họ chỉ khi chúng tôi không cần tuổi và giới tính.

Khi có trục trặc trong nhật ký mạng hoặc máy chủ GraphQL, sẽ dễ dàng xác định truy vấn trong codebase bằng tên thay vì cố gắng giải mã nội dung.

Truy vấn này không cung cấp id đã được yêu cầu và GraphQL cung cấp cho chúng tôi một thông báo lỗi mô tả rất. Bây giờ chúng ta sẽ thực hiện một truy vấn chính xác, chú ý việc sử dụng các biến / đối số.

Query

query getSingleUser($userID: Int!) {
    user(id: $userID) {
        name
        age
        gender
    }
}

Variables

{ 
    "userID":1
}

Output

 Còn tiếp…

TopDev via Scotch

  Tại sao bây giờ là thời điểm thích hợp để học GraphQL?

 

1001 Tips: Con trỏ và hàm (Pointer & Function) trong C++

Con trỏ và tham số của hàm

Chúng ta đã tìm hiểu về 2 kiểu tham số của hàm:

  • Hàm có tham số nhận giá trị: giá trị truyền vào hàm có thể là giá trị của biến, một hằng số hoặc một biểu thức toán học…
  • Hàm có tham số kiểu tham chiếu: giá trị truyền vào cho hàm là tên biến, và tham số của hàm sẽ tham chiếu trực tiếp đến vùng nhớ của biến đó.

Chúng ta còn có thêm một kiểu truyền dữ liệu vào cho hàm nữa, đó là truyền địa chỉ vào hàm (Pass arguments by address). Do đó, kiểu tham số của hàm có thể nhận giá trị là địa chỉ phải là con trỏ.

void foo(int *iPtr)
{
	cout << "Int value at " << iPtr << " is " << *iPtr << endl;
}

int main()	
{
	int iValue = 10;
	foo(&iValue);
	
	system("pause");
	return 0;
}

Trong đoạn chương trình trên, sau khi truyền địa chỉ của biến iValue vào hàm foo, tham số iPtr bây giờ sẽ giữ địa chỉ của biến iValue, và chúng ta có thể sử dụng toán tử dereference cho con trỏ iPtr. Kết quả in ra màn hình trên máy tính của mình là:

Int value at 0xBFBA144C is 10

Nếu vùng nhớ tại địa chỉ được sử dụng làm đối số cho hàm không phải là hằng, chúng ta có thể thay đổi giá trị của vùng nhớ đó ngay bên trong hàm thông qua toán tử dereference:

void changeValue(int *iPtr)
{
	*iPtr = 10;
}

int main()
{
	int iValue = 5;
	cout << "Value = " << iValue << endl;
	
	changeValue(&iValue);
	cout << "Value = " << iValue << endl;
	
	system("pause");
	return 0;
}

Kết quả in ra:

Value = 5
Value = 10

Như vậy, chúng ta có thể hoán vị giá trị của 2 số nguyên thông qua hàm như sau:

void swapIntValue(int *ptr1, int *ptr2)
{
	int temp = *ptr1;
	*ptr1 = *ptr2;
	*ptr2 = temp;
}

int main()
{
	int value1 = 2;
	int value2 = 5;
	
	cout << "Before swap: " << value1 << " " << value2 << endl;
	swapIntValue(&value1, &value2);
	cout << "After swap : " << value1 << " " << value2 << endl;
	
	system("pause");
	return 0;
}

Kết quả:

Before swap: 2 5
After swap : 5 2

Như các bạn thấy, con trỏ khi làm tham số cho hàm cũng có khả năng thay đổi giá trị của vùng nhớ không phải hằng như con trỏ thông thường thông qua toán tử dereference.

Chúng ta còn có thể truyền địa chỉ của mảng một chiều vào cho tham số kiểu con trỏ của hàm. Ví dụ:

void printArray(int *arr, int length)
{
	for (int i = 0; i < length; i++)
	{
		cout << arr[i] << " ";
	}
	cout << endl;
}

int main()
{
	int iArr[] = { 3, 2, 5, 1, 7, 10, 32 };
	printArray(iArr, sizeof(iArr) / sizeof(int));
	
	system("pause");
	return 0;
}

Lưu ý, chúng ta không thể biết chính xác kích thước của mảng một chiều thông qua con trỏ, do đó, chúng ta cần tính toán trước kích thước của mảng trước khi truyền vào cho hàm.

Sử dụng Pointer to const để làm tham số cho hàm

Như các bạn đã biết, Pointer to const là loại con trỏ chỉ có chức năng để đọc (read-only). Do đó, sử dụng Pointer to const làm tham số cho hàm sẽ đảm bảo rằng giá trị tại vùng nhớ được truyền vào cho hàm sẽ không bị thay đổi.

void printArray(const int *arr, int length)
{
	for (int i = 0; i < length; i++)
	{
		cout << arr[i] << " ";
	}
	cout << endl;
}

int main()
{
	int arr[] = {};
	int length = sizeof(arr) / sizeof(int);
	
	printArray(arr, length);
	
	system("pause");
	return 0;
}

Lúc này, chúng ta có thể đảm bảo rằng giá trị của các phần tử trong mảng arr sẽ không bị thay đổi bởi hàm printArray.

Tham số của hàm là tham chiếu vào con trỏ

Khi chúng ta truyền đối số cho hàm là một địa chỉ, cái địa chỉ này cũng chỉ là bản copy của địa chỉ ban đầu. Về bản chất, truyền địa chỉ vào hàm là truyền đối số là giá trị (pass by value). Địa chỉ của đối số sẽ được copy và gán lại cho tham số con trỏ của hàm. Nếu bên trong hàm có câu lệnh thay đổi địa chỉ được truyền vào, chúng chỉ thay đổi bản sao của địa chỉ gốc. Để dễ hình dung hơn, chúng ta xem xét ví dụ sau:

void setToNull(int *ptr)	
{
	ptr = NULL; // (4)
}  // (5)

int main()
{
	int value = 5;
	int *pValue = &value; // (1)
	
	cout << "pValue point to " << pValue << endl; // (2)
	setToNull(pValue); // (3)
	cout << "pValue point to " << pValue << endl; // (6)
	
	system("pause");
	return 0;
}

Có 6 bước để nói về đoạn chương trình trên:

(1) Gán địa chỉ của biến value cho con trỏ pValue.
(2) In ra địa chỉ mà con trỏ pValue đang nắm giữ.
(3) Truyền giá trị của con trỏ đang nắm giữ cho hàm setToNull
(4) Sau khi con trỏ ptr trong hàm setToNull nhận được giá trị đầu vào, con trỏ ptr này được gán lại giá trị NULL.
(5) Ra khỏi phạm vi của hàm setToNull, con trỏ ptr bị hủy.
(6) In ra lại giá trị của con trỏ pValue. Lúc này, chúng ta có thể thấy giá trị của pValue không hề thay đổi, nó vẫn còn trỏ đến địa chỉ của biến value.

Như vậy, giá trị địa chỉ được truyền vào hàm được nắm giữ bởi tham số con trỏ của hàm, từ đó chúng ta có thể sử dụng toán tử dereference để thao tác với vùng nhớ tại địa chỉ đó. Chúng ta cũng có thể cho tham số của hàm trỏ đến địa chỉ khác, nhưng không ảnh hưởng gì đến con trỏ gốc.

Trong một số trường hợp cụ thể, chúng ta muốn thay đổi địa chỉ của con trỏ đối số đang trỏ đến, chúng ta có thể sử dụng tham chiếu cho con trỏ đối số. Xét đoạn chương trình bên dưới:

void setToNull(int *&ptr)	
{
	ptr = NULL;
}

int main()
{
	int value = 5;
	int *pValue = &value;
	
	cout << "pValue point to " << pValue << endl;
	setToNull(pValue);
	if(pValue == NULL)
		cout << "pValue point to NULL" << endl;
	else
		cout << "pValue point to " << pValue << endl;
	
	return 0;
}

Kết quả của đoạn chương trình này cho thấy con trỏ pValue sau khi truyền vào hàm setToNull đã được gán giá trị NULL. Do tham số con trỏ của hàm setToNull là một tham chiếu kiểu (int *), nó sẽ tham chiếu đến đối số được truyền vào, trong trường hợp này, tham số tham chiếu con trỏ ptr có cùng địa chỉ với pValue, việc thay đổi giá trị mà ptr nắm giữ cũng làm thay đổi giá trị của pValue.

  Modern C++ binary RPC framework gọn nhẹ, không cần code generation

Con trỏ và kiểu trả về của hàm

Chúng ta đã cùng tìm hiểu 2 kiểu giá trị trả về của hàm có kiểu trả về:

  • Hàm trả về giá trị.
  • Hàm trả về tham chiếu.

Bây giờ, chúng ta sẽ cùng tìm hiểu một số vấn đề về kiểu giá trị trả về của hàm là địa chỉ (return by address).

Khi nói về việc trả về địa chỉ từ hàm, chúng ta hiểu rằng đó là địa chỉ của những biến hoạt động bên trong hàm. Địa chỉ này sẽ được trả về cho lời gọi hàm, và địa chỉ này thường được tiếp tục sử dụng bằng cách gán nó lại cho 1 con trỏ. Do đó, kiểu trả về của hàm cũng phải là kiểu con trỏ.

Ví dụ:

int * createAnInteger(int value = 0)
{
	int myInt = value;
	return &myInt;
}

int main()
{
	int *pInt = createAnInteger(10);
	cout << *pInt << endl;
	
	return 0;
}

Sau khi nhìn vào kết quả, chúng ta thấy có vẻ chương trình đã cho ra kết quả như mong muốn:

10

Nhưng thực chất, đoạn chương trình trên đã gây ra lỗi nghiêm trọng. Lý do là biến myInt được khai báo bên trong hàm là biến cục bộ, được cấp phát bằng kỹ thuật Automatic memory allocation, và vùng nhớ được cấp phát cho biến myInt được lưu trữ trên phân vùng Stack của bộ nhớ ảo. Do đó, ngay sau khi ra khỏi hàm, vùng nhớ của biến myInt đã bị hệ điều hành thu hồi, nhưng địa chỉ của biến myInt trước đó đã được trả về cho lời gọi hàm, nên con trỏ pInt trong hàm main được gán một địa chỉ của một vùng nhớ không thuộc quyền quản lý của chương trình hiện hành nữa.

Như mình đã nói, nếu không may, một chương trình khác yêu cầu cấp phát vùng nhớ ngay tại địa chỉ của biến myInt lúc chưa bị hủy, nội dung bên trong vùng nhớ này sẽ bị các chương trình khác thay đổi, dẫn đến việc sử dụng toán tử dereference đến vùng nhớ đó không cho ra kết quả như ban đầu nữa. Các bạn có thể chạy đoạn chương trình sau để kiểm chứng:

int * createAnInteger(int value = 0)
{
	int myInt = value;
	return &myInt;
}

int main()
{
	int *pInt = createAnInteger(10);
	cout << "Print immediately:         " << *pInt << endl;
	_sleep(1000);
	cout << "After a fews seconds:   " << *pInt << endl;

	system("pause");
	return 0;
}

Kết quả trên máy tính của mình:

Như các bạn thấy, chỉ sau thời điểm vùng nhớ của biến myInt bị hủy mới có 1 giây mà đã có chương trình khác sử dụng vùng nhớ đó, làm cho giá trị in ra màn hình console không còn như ban đầu nữa. Và nếu không may hơn nữa, nếu chương trình khác sử dụng cơ chế đồng bộ của kỹ thuật multithreading lên vùng nhớ này, việc dereference vào vùng nhớ đó cũng có thể gây crash chương trình.

Nguyên nhân của những hệ quả mà mình vừa kể ra đều là do vùng nhớ được cấp phát trên Stack thông qua kỹ thuật Automatic memory allocation sẽ bị thu hồi tự động bởi hệ điều hành. Để giải quyết vấn đề này, chúng ta cần sử dụng phân vùng Heap để có thể tự quản lý thời điểm giải phóng vùng nhớ để trả lại cho hệ điều hành quản lý.

int * createAnInteger(int value = 0)
{
	return new int(value);
}

int main()
{
	int *pInt = createAnInteger(10);
	
	cout << "Print immediately:   " << *pInt << endl;
	_sleep(5000);
	cout << "After a few seconds: " << *pInt << endl;
	
	system("pause");
	return 0;
}

Kết quả lúc này đã được đảm bảo do chúng ta biết rằng vùng nhớ cấp phát trên Heap chỉ bị hệ điều hành thu hồi khi toàn bộ chương trình kết thúc.


Tổng kết

Trong bài học này, chúng ta đã biết cách truyền tham số là địa chỉ (hoặc con trỏ) vào cho hàm, và trả về địa chỉ cho lời gọi hàm. Bên cạnh đó, chúng ta cũng đã biết được một số vấn đề phát sinh khi sử dụng các kỹ thuật này. Vẫn còn nhiều vấn đề cần phải nói khi sử dụng con trỏ, chúng ta sẽ cùng tiếp tục tìm hiểu trong các bài học tiếp theo.

Bài tập cơ bản

Xét đoạn chương trình của ví dụ trên.

#include <iostream>
using namespace std;

int * createAnInteger(int value = 0)
{
	return new int(value);
}

int main()
{
	int *pInt = createAnInteger(10);
	
	cout << "Print immediately:   " << *pInt << endl;
	_sleep(5000);
	cout << "After a few seconds: " << *pInt << endl;
	
	system("pause");
	return 0;
}

Đoạn chương trình trên cho ra kết quả đúng, giá trị được in ra khi sử dụng toán tử dereference để truy xuất không bị thay đổi theo thời gian, nhưng nó lại phát sinh một vấn đề khác. Đó là vấn đề gì?

TopDev via daynhauhoc.com

  1001 Tips: Con trỏ và hàm (Pointer & Function) trong C++
Lương của Developer (C++, PHP) tại Cốc Cốc có thể lên đến $2,000?”]

5 tips cải tiến chất lượng phát triển Mobile App

Với Mobile App Development (MAD), chất lượng nói lên tất cả, hay nói cách khác App càng chất lượng, khách hàng càng tin tưởng. Vậy làm thế nào để cải thiện chất lượng App là một câu hỏi hàng đầu khi bắt tay vào mọi project. Hãy cùng TopDev điểm qua những tips cực hữu ích dành cho Mobile Application Development dưới đây nhé.

Cập nhật dữ liệu không ngừng

Cập nhật dữ liệu không ngừng

Dữ liệu được liên tục được cập nhật luôn làm hài lòng người dùng. Thực tế, có rất nhiều ứng dụng yêu cầu vấn đề này, từ book vé xem phim, vé máy bay và những yêu cầu khác để truyền tải thông tin mới nhất. Tuy nhiên chiến lược truyền tải thông tin đến khách hàng lại là một điều quan trọng khác khi di động đang phát triển mạnh mẽ và bạn nên biết phải vận dụng điều này.

Song, một lỗi nhỏ trong việc đặt vé cũng có thể làm sập đổ cả ứng dụng hoặc tệ hơn là làm mất lòng tin của khách hàng.

Độ phản hồi chính xác

Độ phản hồi chính xác

Độ phản hồi là một trong những yếu tố quan trọng mà bạn không nên mạo hiểm nếu không muốn đánh mất sự hài lòng của khách hàng khi họ thực hiện các hoạt động trên mobile, đặc biệt trải nghiệm của khách hàng sẽ quyết định sự thành bại tới app của bạn. Vậy nên, độ chính xác và tốc độ phản hồi là hai yếu tố quan trọng nhất mà chúng ta cần quan tâm về response khi tạo app. Nếu bạn gặp rắc rối về chúng, các vấn đề này có thể được giải quyết khi chọn những nền tảng (platform) được cải tiến.

Khả năng mở rộng và phát triển

Khả năng mở rộng và phát triển

Đây thực sự là yếu tố quan trọng khi viết app. Đừng bao giờ nghĩ rằng App của bạn sẽ bị ràng buộc với một lượng khách hàng cụ thể. Bạn nên xây dựng app dựa trên những giải pháp khác nhau có khả năng thích ứng trong tương lai. Thử hình dung mobile app của bạn trở nên viral cùng với sự gia tăng khách hàng và lượt tải về. Từ đó, tính linh hoạt cũng như lượt sử dụng, không gian, tốc độ và database, … nên được ưu tiên hàng đầu.

Khả năng truy cập đa nền tảng

Khả năng truy cập đa nền tảng

Mọi thứ nên được cân nhắc kỹ lưỡng khi xây dựng bất kỳ ứng dụng nào, vì chúng ta không lường trước điều gì là cần thiết trong tương lai. Vậy nên sao không hiện thực hóa những platform tân tiến ngay từ đầu, điều này giúp giảm thiểu việc đau đầu khi phát triển app trong tương lai.

Rất nhiều khách hàng khi có ứng dụng android đã yêu cầu một phiên bản iOS trong tương lai và ngược lại. Nên nếu sử dụng những platform đa nền tảng, chúng ta sẽ tiết kiệm được khá nhiều thời gian và chi phí.

Những lưu ý về độ an toàn

Những lưu ý về độ an toàn

Khi tạo ra những app có thể trao đổi dữ liệu doanh nghiệp cơ bản, chúng ta phải chú ý đến việc giải quyết lỗ hổng an ninh. Khâu xác thực khách hàng phù hợp phải tiến hành để đảm bảo tính bảo mật của bất kỳ dữ liệu hay thông tin nhạy cảm có khả năng bị rò rỉ qua ứng dụng.

Có khá nhiều tổ chức xây dựng app mobile trên toàn thế giới. Để nổi bật hơn những tổ chức này, app của bạn phải đạt chuẩn, được xác minh vượt trội hơn hẳn để gây ấn tượng với khách hàng của mình. Khi xem xét tất cả những điều trên, khả năng ROI (Hệ số thu nhập trên đầu tư) được nâng cao là điều dễ hiểu.

Việc tạo ra một app đầy thú hút thì bạn hoàn toàn có khả năng kiếm một khoảng tiền lớn, tuy nhiên sự đầu tư cho một app là không nhỏ và cải thiện nó lại là quá trình lâu dài mới khiến app của bạn sống sót trong trong thời đại mobile. 5 tips về Mobile App Development trên không nhiều cũng không ít nhưng cũng đủ để bạn hình dung được đâu sẽ là sự quyết định cho thành công cho “đứa con cưng” của mình.

source: masif

Cập nhật mới nhất, ứng dụng nhiều hơn, lắng nghe nhiều hơn các chia sẻ từ chuyên gia  trong lĩnh vực Mobile Technology & Digital và hơn hết là kết nối cộng đồng tại Vietnam Mobile Day 2019, sự trở lại của năm thứ 9 không khiến khán giả thất vọng!

Lập trình đâu chỉ có những dòng code

Lập trình đâu chỉ có những dòng code

Lập trình đâu chỉ là những dòng code – TopDev via Persol

Học lập trình thế nào để không thất nghiệp?

Dạy học ở VN là một bài toán chưa có lời giải. Học xong, tốt nghiệp nhiều nhưng thất nghiệp và làm trái ngành cũng nhiều. Tôi muốn góp phần giải bài toán này để có nhiều người có thể làm đúng đam mê của mình.

Trước hết, người viết xin nói lên quan điểm của mình về vấn đề này, tại sao người học lập trình lại không thể xin việc, hay nói cách khác là không thể lập trình đúng nghĩa. Theo tôi đó là do cách dạy học ở mình còn nặng thành tích và tập trung vào cách làm sao có điểm cao là được.

Trường phổ thông thì tôi không nói, mọi người lao đầu vào học và giải bài để đi thi ĐH. Nhưng lên ĐH rồi, tôi còn thấy nhiều bạn đi học kèm thì tôi cảm thấy quá thất vọng. Tôi từng viết một bài có hơi chua chát, cách học lập trình thất bại. Mọi người vẫn có tư tưởng ở phổ thông là giải thật nhiều bài tập, xin đừng hiểu sai ý của tôi. Tôi không phê phán việc giải nhiều bài tập, nhưng cái tôi muốn nói tới là giải bài tập vừa đủ để hiểu vấn đề. Đừng giải quá nhiều bài tập để thành thợ giải toán, thợ giải bài tập mà không đi sâu được. Mọi người cứ nghĩ lên ĐH rồi vẫn cần phải đi học kèm, phải giải thật nhiều dạng đề. Cái gì, giải nhiều dạng đề để làm gì? Doanh nghiệp họ đâu có tuyển lập trình viên vào giải đề? Trừ phi bạn giải đề để đi thi competitive programming.

Như hôm nay tôi có trả lời một câu hỏi của một bạn, bạn ấy hỏi thợ code là gì? Theo tôi, thợ code là người code nhanh, code nhiều, code không cần nghĩ. Ở đâu thì có thợ code, ở các nước đang phát triển như VN thì thợ code rất nhiều.

Các bạn học lập trình, không học cơ bản, thích học công nghệ. Ra trường vào một công ty outsource, không phải mọi outsource đều xấu, tôi chỉ đang ví dụ một số công ty outsource cơ bắp. Khách hàng từ các nước phát triển không muốn phí tiền làm công việc cơ bắp, họ gửi đơn hàng về VN. Khi này, các thợ code có cơ hội ra tay, code mỗi ngày rất nhiều, mỗi tháng có thể làm được vài KLOC (K line of code) nhưng cứ code đi code lại một vài tính năng quản lý thành quen. Sau cùng, từ một người đam mê công nghệ, bạn mình, có người muốn bỏ nghề làm cái khác. Nhưng cuối cùng cũng vì cơm áo gạo tiền mà lại tiếp tục nai lưng ra làm thợ code.

Khi đi học trên trường, có giai đoạn tôi rất thích học. Đó là khi được học cơ bản, biết về biến, con trỏ, hàm, class. Đó là khi được học giải thuật, học cách bảng băm hoạt động, cách mã hóa dữ liệu, cách nén và giải nén, cách xử lý ảnh, học về trí tuệ nhân tạo, …. Đó mới chính là những cái tôi thích học, tuy nhiên tôi muốn nhấn mạnh đây là sở thích cá nhân, cũng không cho rằng mọi người nên hoặc phải có cùng sở thích với tôi.

Nhưng cái tôi muốn dạy cũng gần như những cái ở trên, đó là dạy cách suy nghĩ của một kỹ sư phần mềm chứ không phải dạy để ra làm thợ code. Dạy những cái thật sự cơ bản, nguyên lý của mọi thứ. Có thể tôi không làm được trong một sớm một chiều, vì khả năng của tôi cũng có giới hạn, nhưng nhất định tôi sẽ không bỏ. Nếu không đủ kiển thức, tôi sẽ học thêm để có thể truyền đạt lại cho mọi người.

Cái tôi nhìn thấy sau mấy năm đi làm là một người học CNTT ra, nhưng không có tư duy lập trình không có giải thuật, không có tìm hiểu, chỉ code như cái máy code thì không thể nào so sánh được với một người không cần từ ngành CNTT ra, nhưng họ có đam mê, họ muốn tìm hiểu, họ học hỏi từ người khác. Họ nghĩ trước khi code, họ nghĩ trước khi làm.

Những người này, tôi không có khả năng dạy, bởi vì hầu hết họ giỏi hơn tôi.

Tóm lại, tôi nghĩ học CNTT ta cần phải có đam mê, nắm cơ bản ngôn ngữ lập trình, cấu trúc dữ liệu & giải thuật, sau đó tự tìm hiểu cái mình cần. Tôi sẽ cố gắng đem những điều đó vào trong khóa học C++. Tên nó là khóa học C++ nhưng bản chất là học cách lập trình thông qua ngôn ngữ C++.

Một điều tôi rất may mắn học được ở ĐH KHTN là những kiến thức cơ bản. tôi và những bạn học cùng lớp từng có nhiều lần nói chuyện với nhau sau khi ra trường rằng thực ra chỉ cần học 2 năm là đi làm được. Bỏ đi 1 năm đại cương, bỏ đi năm 4 học “phân tích phát triển phần mềm”, chỉ cần 2 năm là đủ đi làm.


Note về Competitive programming:

Competitive programming là cái gì?

Đây là các cuộc thi giải thuật, bạn phải thật sự giỏi giải thuật thì mới có thể chiến thắng ở các cuộc thi này. Giống như các cuộc thi toán.

Cái này có tốt cho học lập trình hay không?

Tôi nghĩ là có, competitive programming yêu cầu bạn có hiểu biết sâu về giải thuật.

Cái này có giúp ta làm ra phần mềm tốt không

Theo tôi nghĩ là không, competitive programming hầu hết là giải các bài toán, code để giải các bài toán này thường gói gọn trong một hàm. Làm phần mềm tốt yêu cầu nhiều hơn thế.

Có giải cao khi thi các giải này có lợi cho việc kiếm việc làm không?

Cá nhân tôi thì nghĩ là không lợi không hại. Robert Love, người phát triển Kernel cho Android và đang ở trong hội đồng tuyển dụng của Google, cho rằng có giải trong các ký thi này không có ý nghĩa gì đối với ổng.

Robert Love’s answer trên Quora

Các câu trả lời khác của các câu hỏi tương tự, có cùng chung quan điểm với Love.

Người viết Lê Trần Đạt

TopDev via Daynhauhoc

  Liệu tôi có làm Junior Developer "mãn kiếp"?
  Làm kỹ sư AI, mức lương 500 triệu là bình thường

Autosaving cùng Vuex

Một vài thông tin background

Vào thời đâu những năm 2000, nếu tôi đang sử dụng Microsoft Word và rồi tắt máy mà quên nhấn Ctrl+S, chắc chắn tôi đã không sống yên ổn. Mọi công sức ra đi và không cách nào có thể lấy lại nó. Trong các phiên bản mới của Word họ đã cho ra mắt công cụ autorecovery, nghĩa là nếu may mắn thì bạn sẽ lấy lại một phần nào đó. Điều này rất tuyệt nhưng MVP thực thụ chính là Google Docs, với indicator luôn tự động sao lưu, sẽ lưu ý bất cứ khi nào bạn đổi doc và tự động lưu nó lên cloud sau mỗi giây.

Autosave đang thực sự thay đổi cuộc chơi. Nếu app cho phép user nhập content, chúng sẽ không cần phải tìm kiếm nút “Save” nữa. Chúng chỉ làm sao để upload lên cloud nhanh nhất có thể ngay khi được nhập vào. May thay, với các webapp hiện đại thì không quá khó để ứng dụng nó.

Hôm nay tôi sẽ chỉ cho bạn cách viết một autosaver dùng Vue.js, Vuex và một cái plugin Vuex. Một điều tốt về method này đó là nó không yêu cầu app bạn phải gửi đi API request mỗi lần có thay đổi; thay vì thế Vuex plugin sẽ xem state của app và phản ứng khi cần, cách ly các công việc nội bộ của app từ tương tác của nó với API. Tôi đã ứng dụng nó vào project ưa thích của tôi, Edward, và nó chạy như một giấc mơ.

Các thành phần

Đây là một vài tool chúng ta sẽ sử dụng:

  • Vue.js là một framework đơn giản và quyền lực để viết web component. Nó tương đương với React về quy mô và mô hình, nhưng đầy đủ shortcut làm nó trở nên dễ sử dụng hơn.
  • Vuex là một tool quản lý state cho Vue. Nó giống với Redux. Nó là một cơ chế immutable state, nghĩa là nó quản lý một object lớn đầy data mà app bạn cần, và mỗi lần data thay đổi thì nó sẽ cho ra một object hoàn toàn mới.
  • Lodash là một JavaScript toolchain (giống như Underscore hoặc một phần cảu jQuery) rất nhiều thứ thú vị. Chúng ta chỉ cần một function từ nó. và chúng ta có thể qua được mà không cần nó, nếu chúng ta muốn.
  • Một web browser.

Một mẫu repo ở đây. Và đoán xem? Không cần đến npm install, không cần build step (bạn có thể mở index.html ngay trên browser), và mọi thứ chỉ dưới 100 dòng code (không tính comment). Ngoài ra, tất cả đều là ES5 thuần.

Có thể bạn muốn xem:

  15 chứng chỉ "vàng" đáng giá trong ngành lập trình
  Mười điều răn dành cho lập trình viên

Cách thực hiện

Đầu tiên bạn cần một file index.html basic. Nó chứa div để Vue đính vào, các tag <script> chó các thư viện chúng ta cần, một tag <script> cho file JavaScript, và một tag <style>  để làm mọi thứ trông nhẹ nhàng hơn.

<body>
  <div id="app"></div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="https://unpkg.com/vuex@3.0.1/dist/vuex.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
<script src="./index.js"></script>
<style>
  textarea {
    height: 100px;
    width: 300px;
  }
</style>

Bạn có thể thấy chúng ta đang thử trên Vue, Vuex, Lodash và file JavaScript riêng tên là index.js. Nó dùng cho file này.

Tạo file index.js. Chúng ta sẽ bắt đầu bằng bootstrap Vue app của chúng ta:

var app = new Vue({
  el: '#app',
  template: '<div></div>',
})

Bạn nên giữ đoạn code này ở cuối file index.js, vì nó sẽ liên hệ với mọi thứ chúng ta build từ đây.

Vue sẽ tìm được element match với el selector và kiểm soát nó. Hiện tại nó sẽ để một<div></div> trong đó. Chúng ta cần nó làm gì khác thú vị hơn lúc này.

Bây giờ hãy tạo một component để user nhập text vào:

Vue.component('text-entry', {
  template: '<textarea v-model="content" @keyup="registerChange"></textarea>',
  data: function () {
    return {
      content: '' // This is the initial value of the textarea
    }
  },
  methods: {
    registerChange: function () {
      // We'll do something whenever the textarea changes
    }
  }
})

Nó sẽ hiện textarea và update value của content bất cứ khi nào user gõ vào. Add nó vào app của chúng ta bằng cách update Vue constructor:

var app = new Vue({
  el: '#app',
  template: '<div> <text-entry></text-entry> </div>',
})

Bây giờ ta cần thấy textarea trong app. Sau đó, sẽ tạo ra một Vuex store:

var store = new Vuex.Store({
  state: {
    content: ''
  },
  mutations: {
    'UPDATE_CONTENT': function (state, newContent) {
      state.content = newContent
    }
  }
})

Đây là store Vuex khá basic. Nó có một phần data và một mutation. Khi bạn trung thành với mutation, nó sẽ save bất kì thứ gì chsng ta đi qua như một giá trị mới của content.

Chúng ta cần store này ở 3 chỗ:

  • Một cái trong app declaration thì Vue biết cách dùng.
  • Một cái trong app declaration của component text-entry, nên nó sẽ đặt giá trị của textarea dựa trên tình trạng của Vuex.
  • Một cái trong method registerChange của component text-entry, để gắn với mutation mọi chỗ user thay đổi text trong textarea.

Khi chúng ta đã thực hiện cả ba, file index.js sẽ như thế này:

var store = new Vuex.Store({
  state: {
    content: ''
  },
  mutations: {
    'UPDATE_CONTENT': function (state, newContent) {
      state.content = newContent
    }
  }
})

Vue.component('text-entry', {
  template: '<textarea v-model="content" @keyup="registerChange"></textarea>',
  data: function () {
    return {
      content: this.$store.state.content
    }
  },
  methods: {
    registerChange: function () {
      this.$store.commit('UPDATE_CONTENT', this.content)
    }
  }
})

var app = new Vue({
  el: '#app',
  template: '<div> <text-entry></text-entry> </div>',
  store: store
})

Để giải thích feature autosaving, chúng ta cần một nơi để store data để vẫn cố định sau khi refresh page. Tôi không dính dáng đến những vấn đề liên quan đến tạo web server cho mục đich này. Thay vì thế hãy dùng LocalStorage:

var storageKey = 'content'
var api = {
  load: function () {
    var json = window.localStorage.getItem(storageKey) || JSON.stringify('')
    return JSON.parse(json)
  },
  save: _.debounce(function (content, callback) {
    window.localStorage.setItem(storageKey, JSON.stringify(content))
    callback()
  }, 1000, { maxWait: 3000 })
}

Fake API của chúng ta có hai method, save và loadload dùng để đưa state khỏi LocalStorage, và nếu nó không ở đó, trả về một string rỗng. Còn save đưa giá trị cho LocalStorage key, và yêu cầu callback. Chúng ta sử dụng method debounce của Lodash để đảm bảo rằng save không bao giờ bị call hơn 1 lần mỗi giây. Quan trọng là vì nếu chúng ta không debounce method này, nó sẽ bị call mỗi lần user gõ một key. Điều này không quá tệ với LocalStorage, nhưng nếu bạn đang thực hiện các request XHR, một user nhập 70 từ trên một phút có thể submit nhiều request trên giây, có thể làm chậm mọi thứ và cả bạn nữa. Tôi đã sử dụng parameter maxWait, để đảm bảo nếu user gõ liên tục, content sẽ được autosave mỗi 3 giây.

Bây giờ, chúng ta có thể tạo một Vuex plugin để autosave content trong textarea. Một Vuex plugin là một function chấp nhận Vuex store như một argument. Nó có thể subscribe vào store để được thông báo mỗi khi state thay đổi.

var autosaverPlugin = function (store) {
  store.commit('UPDATE_CONTENT', api.load())

  store.subscribe(function (mutation, state) {
    if (mutation.type === 'UPDATE_CONTENT') {
      api.save(mutation.payload, function () {
        // This callback doesn't need to do anything yet
      })
      return
    }
  })
}

Khi plugin được load lần đầu, ngay lập tức sẽ load application state từ LocalStorage và theo nó như một mutation. Sau đó chúng ta subscribe vào Vuex store. Mỗi lần mutation commit, chúng ta sẽ đươc báo. Chúng ta có thể check loại mutation để đảm bảo content được update, sau đó gửi đi payload vào fake API để lưu trên LocalStorage.

Bây giờ hãy add plugin này vào Vuex declaration:

var store = new Vuex.Store({
  state: {
    content: ''
  },
  mutations: {
    'UPDATE_CONTENT': function (state, newContent) {
      state.content = newContent
    }
  },
  plugins: [autosaverPlugin]
})

Nếu bạn nhập vào textarea, đợi một chút và refresh page, bạn sẽ thấy một vài thay đổi nhỏ. Và vue component không phải quan tâm về nó; Vuex plugin đã làm hết những việc nặng nề.

Bước cuối

Chúng ta có thể dùng một cách để báo cho user biết những gì họ làm đã được lưu. Nó sẽ đảm bảo lại cho user và giúp bạn nắm được là app vẫn hoạt động bình thường. Hãy add một vài text hiển thị “Saving…” hoặc “Saved”.

Đầu tiên, add một vài state vào Vuex store:

var store = new Vuex.Store({
  state: {
    content: '',
    saveStatus: 'Saved'
  },
  mutations: {
    'SET_SAVE_STATUS': function (state, newSaveStatus) {
      state.saveStatus = newSaveStatus
    },
    'UPDATE_CONTENT': function (state, newContent) {
      state.content = newContent
    }
  },
  plugins: [autosaverPlugin]
})

saveStatus sẽ chứa một string thông báo cho user phần của họ đã được lưu chưa. Và SET_SAVE_STATUS sẽ update nó.

Bây giờ chúng ta sẽ tạo một component để hiển thị nó:

Vue.component('saving-indicator', {
  template: '<div>{{ saveStatus }}</div>',
  computed: {
    saveStatus: function () {
      return this.$store.state.saveStatus
    }
  }
})

Và cho hiện nó ở trên textarea bằng cách chỉnh app template:

var app = new Vue({
  el: '#app',
  template: '<div> <saving-indicator></saving-indicator> <text-entry></text-entry> </div>',
  store: store
})

Hãy update autosaver plugin để commit các mutation với saveStatus:

var autosaverPlugin = function (store) {
  store.commit('UPDATE_CONTENT', api.load())

  store.subscribe(function (mutation, state) {
    if (mutation.type === 'UPDATE_CONTENT') {
      store.commit('SET_SAVE_STATUS', 'Saving...')
      api.save(mutation.payload, function () {
        store.commit('SET_SAVE_STATUS', 'Saved')
      })
      return
    }
  })
}

Và cuối cùng, file index.js trông giống như mẫu trong repo. Xem thử tại đây: https://github.com/isaaclyman/vuex-autosaver/blob/master/index.js

Hãy thử xem! Khi bạn nhập vào textarea, message báo “Saving…” và một khi hoàn thành, nó sẽ báo “Saved”. Giống như trong Google Docs. Một công cụ web development đỉnh cao tại đây.

Homework

Đây là một vài thứ bạn có thể add vào project để không phải dính vào rắc rối:

  • Saving indicator có thể báo”Error” nếu có lỗi trong api.save method.
  • Fake API có thể dùng timeout để giả mạo một XHR request chậm.
  • Fake API cũng có thể return một Promise thay vì chấp nhận callback.
  • Có thể có hai textareas, và mỗi cái có thể autosave bằng càng ít code duplication càng tốt. Gợi ý: Hãy autosave object thay vì cái string.
  • Nếu api.save không nhận callback, nó sẽ hiện error.
  • Mọi thứ có thể trông chuyên nghiệp hơn nhiều. Nó có thể là phiên bản Craigslist của Google Docs.

Tham khảo các vị trí tuyển dụng VueJS lương cao cho bạn tại Topdev.

  Xử lí sự kiện trong VueJS
  Xây dựng ứng dụng chat realtime bằng Laravel + Vuejs + Socket + Redis

Các Tools bạn có thể rất cần cho các React Components của mình

Component là gì? Hiểu về Component trong React và Vue

Là một react developer, tôi tin rằng những ai đang làm một project react phải develop tất cả các components riêng biệt để tận dụng triết lý component đằng sau framework front-end ấn tượng này.

Develop các components riêng biệt giúp bạn kiểm soát được project workflow của bạn, cho phép bạn develop và test mọi component đầu tiên mà không phải lo lắng về logic của cả project, ngoài ra bạn còn có thể cải thiện việc tái sử dụng component, khả năng test và tốc độ dev để đơn giản hóa các task của tổ chức cũng như phân phối đều task trong team.

Nếu đây là lần đầu tiên bạn nghe về storybook hoặc react styleguidist, bài viết này là điểm khởi đầu hoàn hảo để tìm hiểu, nhưng nếu bạn đã từng nghe về nó hoặc làm việc với nó, bài viết vẫn giúp ích vì cung cấp cho bạn nhiều lựa chọn storybook tuyệt vời.

Storybook: (21K Stars)

alt text

Một trong những react tool phổ biến và quyền lực nhất để build components, được tả trong GitHub như một component interactive UI dev & test mà có support react, react-native, vue và angular.

Nói cách khác, storybook như một môi trường dev UI components. Nó cho phép bạn browse tất cả các components project và view các states khác of mỗi component.

Storybook mang theo rất nhiều add-ons cho việc design components, tư liệu, test và hơn thế. Từ ví dụ này, bạn có thể thử hết với các component props một cách dễ dàng bằng các add-on storybook prop.

Bạn có thể dùng storybook-preview và storybook-deploy để tạo và triển khai các stories như một documentation static website.

React Cosmos: (4k Starts)

alt text
Cosmos sẽ scan project của bạn để tìm component và cho phép bạn render các components trong các bộ props, context, và state bất kì. Nó cũng đồng nghĩa là bạn đã bắt tay vào project và bạn cần add các functionalities mới vào components mà không phát điên lên.

Cosmos sẽ Mock mọi external dependency như API còn lại của bạn hoặc local storage. Đồng thời, bạn cũng có thể thấy các states phát triển trong real-time trong khi tương tác với các instances đang chạy, để xử lý hết các features này, Cosmos sử dụng đến fixture và proxy architecture.

React Styleguidist: (4k stars)

alt text

React Styleguidist là một môi trường dev component gồm dev server reloaded và các hướng dần live mà bạn có thể share với team. Nó list ra các component prototypes và hiể thị nó live, các ví dụ usage có thể edit được dựa trên file Markdown và hoạt động cúng react tạo app.

Catalog: (500 stars)

alt text
Catalog là một tool tạo các chỉ dẫn live cho các digital products. Nó kết hợp các tư liệu design và assets bằng các components thực và live tại một chỗ. Tôi nghĩ tool này mạnh hơn cả khi bạn cần hiển thị trên system mình đầy đủ màu design, typography, audio, video và đương nhiên là, react component, cùng nhiều thứ khác trên các trang markdown và nhiều options về size của screen.

Ngoài ra còn có các tool khác như AtellierCarte BlancheReact BlueKitReact CardsReact-demo.

Tham khảo thêm vị trí tuyển dụng React lương cao cho bạn

  67 tools, libraries và resources giúp Web developer "dễ thở" hơn
  Những "mánh khoé" sử dụng React Context

Tuyệt chiêu đảm bảo tính bất biến trong JavaScript

Khi làm việc với React, hẳn bạn đã nghe đến tính bất biến của dữ liệu (immutability). Đặc tính này, nói một cách đơn giản, là khả năng giá trị của dữ liệu không bị thay đổi sau khi đã được khai báo. Tính bất biến giúp cho chương trình trở nên dễ dự đoán, ít xảy ra lỗi và trong một số trường hợp còn tăng hiệu suất của ứng dụng. Do đó, React (và Redux) đều khuyến khích mọi người viết code để hướng đến đặc tính này.

Tuy vậy, nếu mới làm quen với JavaScript và React, có thể bạn sẽ bỡ ngỡ không biết làm thế nào cho “chuẩn nhất”. Bài viết dưới đây giới thiệu một số kỹ thuật giúp bạn hướng đến immutability một cách dễ dàng hơn. Chúng ta sẽ nói về hàm thuần khiết, các thao tác xử lý dữ liệu trên mảng và object. Cuối cùng, bạn có thể áp dụng ngay những “tuyệt chiêu” vừa học để xây dựng một demo nhỏ bằng React.

Luôn dùng const khi khai báo dữ liệu

Lời khuyên đầu tiên và cũng là căn bản nhất, luôn dùng const khi khai báo. Chắc bạn cũng đã biết, let và const được giới thiệu từ phiên bản ES6, cho phép khai báo biến có tầm vực theo khối và không thực hiện hoisting. Điểm khác biệt giữa let và const là bạn có thể thay đổi giá trị của biến khai báo với let, trong khi không thể với const.

let foo = 1
foo = 2 // Không thành vấn đề

const bar = 1
bar = 2 // Error: Assignment to constant variable.

Do đó, trong hầu hết các trường hợp bạn nên khai báo bằng const để tránh xảy ra lỗi khi giá trị của khai báo bị thay đổi bất ngờ. Cũng cần lưu ý là khi khai báo objects với const, mặc dù bạn không thể gán giá trị mới cho object nhưng giá trị của các thuộc tính vẫn có thể bị thay đổi.

const obj = { name: 'foo' }
obj = { name: 'bar' } // Error: Assignment to constant variable.

// Nhưng bạn có thể...
obj.name = 'bar'
console.log(obj) // { name: 'bar' }

Thao tác trên object

Như vậy để thay đổi giá trị của object mà vẫn đảm bảo tính chất bất biến, chúng ta cần sử dụng Object.assign(target, ...sources). Hàm này có tác dụng sao chép thuộc tính của các đối tượng sources vào target. Ví dụ như:

const a = { name: 'foo' }
const b = Object.assign({}, a, { name: 'bar', age: 1 }, { id: 9 })
console.log(b) // { name: 'bar', age: 1, id: 9 }

Cần lưu ý để đảm bảo tính bất biến thì tham số target nên luôn là {}, vì khi đó các giá trị của sources sẽ được sao chép vào đối tượng mới. Một cách dùng sai là:

const a = { name: 'foo' }
const b = Object.assign(a, { name: 'bar', age: 1 }, { id: 9 })
console.log(b) // { name: 'bar', age: 1, id: 9 }
console.log(a) // Giá trị của a cũng bị thay đổi thành { name: 'bar', age: 1, id: 9 }
console.log(a === b) // true

Ngoài Object.assign(), bạn cũng có thể dùng cú pháp spread cho object. Ví dụ:

const a = { name: 'foo' }
const b = { ...a, name: 'bar', age: 1, id: 9 }
console.log(b) // { name: 'bar', age: 1, id: 9 }
console.log(a === b) // false

Lưu ý là cú pháp này hiện vẫn đang được đề xuất và chưa được hỗ trợ trên hầu hết các trình duyệt. Nếu muốn xài thì bạn phải dùng Babel hay Bublé để chuyển đổi nhé.

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

Một số thao tác thường gặp khác trên object

Lấy tên các thuộc tính của một object

const obj = { name: 'bar', age: 1, id: 9 }
Object.keys(obj) // ['name', 'age', 'id']

Lấy giá trị của các thuộc tính của một object

const obj = { name: 'bar', age: 1, id: 9 }
Object.values(obj) // ['bar', 1, 9]

Lấy cặp [thuộc tính, giá trị] của một object

const obj = { name: 'bar', age: 1, id: 9 }
Object.entries(obj) // [ ['name', 'bar'], ['age', 1], ['id', 9] ]

Xóa một thuộc tính ra khỏi object

const a = { name: 'bar', age: 1, id: 9 }

// Xóa thuộc tính age
const b = Object.entries(a).reduce((acc, [key, value]) => {
  return key === 'age' ? acc : { ...acc, [key]: value }
}, {})

console.log(b) // { name: 'bar', id: 9 }
  15 chứng chỉ "vàng" đáng giá trong ngành lập trình
  JavaScript Tip: Đặt tên function để debugging một cách dễ dàng hơn

Thao tác trên mảng

Bên cạnh object, mảng là cấu trúc dữ liệu rất thường gặp khi làm việc trong JavaScript. Để thay đổi dữ liệu của một mảng mà vẫn đảm bảo tính bất biến, bạn có thể sử dụng cú pháp spread, được giới thiệu từ ES5. Với một số yêu cầu khác, chúng ta có thể áp dụng các hàm có sẵn của lớp Array, như map()filter()reduce(). Một đặc điểm của các hàm này là chúng luôn trả về mảng/giá trị mới chứ không thay đổi mảng ban đầu.

Áp dụng cú pháp spread

Bạn có thể dùng spread để nhân bản một mảng.

const a = [1, 2, 3, 4, 5]
const b = a
console.log(a === b) // true

const c = [...a]
console.log(a === c) // false 

Thêm một phần tử vào mảng

const a = [1, 2, 3]

// Không nên: a.push(4)
const b = [...a, 4] // [1, 2, 3, 4]

// Không nên: a.unshift(0)
const c = [0, ...a] // [0, 1, 2, 3]

Nối hai mảng với nhau

const a = [0, 1]
const b = [2, 3]

// Hoặc a.concat(b)
const c = [...a, ...b]

Áp dụng hàm có sẵn để:

Xóa một phần tử ra khỏi mảng các đối tượng

const a = [{ id: 1, name: 'Foo' }, { id: 2, name: 'Bar' }, { id: 3, name: 'Baz' }]

const b = a.filter(obj => obj.id !== 2)
console.log(b) // [ { id: 1, name: 'Foo' }, { id: 3, name: 'Baz' } ]

Xóa một phần tử ở đầu mảng, cuối mảng hay ở bất cứ vị trí nào

const a = [0, 1, 2, 3, 4]

// Xóa phần tử ở đầu mảng
// Không nên: a.shift()
const b = a.filter((_, index) => index !== 0) // [1, 2, 3, 4] 

// Xóa phần tử ở cuối mảng
// Không nên: a.pop()
const c = a.filter((_, index, arr) => index != arr.length - 1) // [0, 1, 2, 3] 

// Xóa phần tử ở vị trí bất kỳ
// Không nên: a.splice(3, 1)
const d = a.filter((_, index) => index !== 3) // [0, 1, 2, 4] 

Thay đổi dữ liệu của mảng

const a = [1, 2, 3]
const b = a.map(x => x * 2) // [2, 4, 6] 

const c = [ { id: 1, name: 'Foo' }, { id: 2, name: 'Bar' }, { id: 3, name: 'Baz' } ]
const d = c.map(obj => Object.assign(obj, { name: obj.name.toUppercase() }))
console.log(d) // [ { id: 1, name: 'FOO' }, { id: 2, name: 'BAR' }, { id: 3, name: 'BAZ' } ]

Sắp xếp mảng: tránh dùng phương thức .sort để sắp xếp mảng, vì phương thức này thay đổi thứ tự của các phần tử trong mảng được sắp xếp. Thay vào đó:

const a = [ { id: 1, name: 'Foo' }, { id: 2, name: 'Bar' }, { id: 3, name: 'Baz' } ]
const b = [...a].sort((x, y) => y.id - x.id)
console.log(b) // [ { id: 3, name: 'Baz' }, { id: 2, name: 'Bar' }, { id: 1, name: 'Foo' } ]

Cũng tương tự khi bạn muốn đảo ngược (reverse) mảng.

const a = [0, 1, 2, 3, 4]
const b = [...a].reverse() // [4, 3, 2, 1, 0]

Trong React, giữ cho phương thức render() thuần khiết

Một hàm được xem là thuần khiết (pure) khi nó luôn trả về cùng một kết quả, nếu giá trị của tham số truyền vào không đổi, đồng thời bản thân hàm không thực hiện những thao tác có thể tạo ra hiệu ứng lề. Ví dụ:

// pure 
function add(x, y) {
  return x + y
}

// impure
function addAndShow(x, y) {
  console.log(x + y)
}

Hàm add() được xem là thuần khiết vì add(2, 3) luôn trả về giá trị 5. Hàm Math.random() thì ngược lại, vì giá trị trả về luôn thay đổi. Bên cạnh đó, addAndShow() cũng bị xem là không thuần khiết, vì nó in kết quả ra console.

Do đó khi làm việc với React, bạn nên xem render() như một hàm thuần khiết với dữ liệu đầu vào là this.props. Hạn chế viết logic bên trong hàm render() mà thay vào đó nên đưa các bước thao tác dữ liệu thành từng phương thức riêng.

Không nên

class Cart extends React.Component {
  render() {
    let total = 0
    for (let i = 0; i < this.props.cart.products; i++) {
      total = this.props.cart.products[i].price + total
    }

    return (
      <div>
        <h1>Cart total: {total}</h1>
        <ProductList products={this.props.sort((a, b) => b.price - a.price)} />
      </div>
    )
  }
}

Nên

class Cart extends React.Component {
  getSortedProducts(cart) {
    return [..cart.products].sort((a, b) => b.price - a.price)
  }

  getCartTotal(cart) {
    return cart.products.reduce((acc, product) => acc + product.price, 0)
  }

  render() {
    const { cart } = this.props

    const total = this.getCartTotal(cart)
    const sortedProducts = this.getSortedProducts(cart)

    return (
      <div>
        <h1>Cart total: {total}</h1>
        <ProductList products={sortedProducts} />
      </div>
    )
  }
}

Hoặc thay vì sử dụng class components, bạn có thể dùng functional components, như kiểu:

function getCartTotal(cart) {
  return cart.products.reduce((acc, product) => acc + product.price, 0)
}

function Cart(props) {
  return <h1>Cart total: {getCartTotal(props.cart)}</h1>
}

Functional components có kha khá lợi ích:

  • Tương đối thuần khiết, vì được thiết kế theo kiểu một props vào, và JSX đi ra. Và không có this.state.
  • Không phải quan tâm đến this
  • Khuyến khích tách biệt phần code xử lý business logic và phần xây dựng giao diện
  • UI được tách thành những component nhỏ, dễ quản lý hơn
  • (Nghe đồn là) nhanh và ít tốn bộ nhớ hơn so với class components

Và dĩ nhiên cũng có những bất lợi:

  • Thiếu đi một số tính năng: không hỗ trợ life-cycle hooks, không có this.state, không có this
  • Không thân thuộc với lập trình viên OOP

Demo

Chúng ta có thể áp dụng những kỹ thuật ở trên để xây dựng một trang liệt kê sản phẩm đơn giản. Bạn có thể xem danh sách sản phẩm, sắp xếp sản phẩm theo tên và giá. Bạn cũng có thể tìm kiếm và xóa sản phẩm. Bên cạnh đó, chúng ta có thể làm thêm 2 nút “rảnh đời”, có tác dụng chuyển tên tất cả sản phẩm sang chữ in hoa, và tăng giá sản phẩm lên gấp đôi. Cuối cùng, trong trang có một nút Reset để khôi phục dữ liệu về lại trạng thái ban đầu.

Bạn có thể xem demo ở đây

Mã nguồn có thể tìm thấy tại: https://github.com/ehkoo/react-immutability-techniques

Kết

Những tuyệt chiêu được đề cập trong bài viết này có thể áp dụng trong tất cả ứng dụng JavaScript, chứ không chỉ dành riêng cho React, Vue hay Angular. Mỗi khi bạn có ý định viết let, hãy hít thật sâu, thở chầm chậm và suy nghĩ cách nào đó để chuyển thành const (và trong đa số trường hợp đều có thể làm được). Đồng thời khi làm việc với mảng hay object, luôn để ý xem thao tác này có thay đổi bản thân của đối tượng bị tác động hay không.

Cho đến ngày JavaScript ràng buộc tính bất biến cho dữ liệu một cách mặc định, lập trình viên chúng ta còn lắm gian truân.

Cập nhật: Ngoài các kỹ thuật ở trên, bạn cũng có thể sử dụng các thư viện được thiết kế riêng cho mục đích giữ tính bất biến, ví dụ như immutable-jsupdeepbaobabseamless-immutable hay mori. Điểm bất lợi khi sử dụng các thư viện này, có lẽ là kích thước của chúng.

TopDev via ehkoo.com

  Tính năng ít được biết đến trong JavaScript
  Những hàm Javascript hay sử dụng mà bạn nên nhớ (Phần 1)

Tìm việc làm IT đãi ngộ tốt trên TopDev

5G & IoT hứa hẹn điều gì trong tương lai?

5G & IoT hứa hẹn điều gì trong tương lai?

“92% thành viên từ 100 nhà khai thác viễn thông mạnh nhất toàn cầu đều thống nhất rằng 5G sẽ mở đường cho các công nghệ mới” – Theo khảo sát của Ericsson

The Fifth Generation – một trong những xu hướng công nghệ hot nhất trong năm 2019 chính là công nghệ truyền thông không dây thứ năm – 5G. 5G được kỳ vọng là chất xúc tác cho các nền công nghiệp khi người người nhà nhà đều sẵn sàng nâng cấp lên 5G. Hệ thống mạng 5G phát huy tầm quan trọng của Internet, biến Internet thành một phần không thể tách rời trong cuộc sống hàng ngày.

Theo suy đoán của Gartner, vào năm 2020 có tới 20,4 tỷ thiết bị sẽ được kết nối và con số này sẽ không dừng lại ở đó. Hiện tại, cơ sở hạ tầng không dây không thể chứa quá nhiều thiết bị và không thể đảm bảo việc trao đổi dữ liệu mượt mà.

mobile and 5G

5G (The Fifth Generation) hứa hẹn một hệ sinh thái thân thiện hơn với IoT (Internet of Things) với những cải tiến vượt bậc so với 4G. Không chỉ truyền dữ liệu với tốc độ cực cao, mà còn giảm độ trễ của mạng (latency) xuống chỉ còn 1 mili giây. Điều này đồng nghĩa với việc 1 bộ phim HD có thể tải xuống trong vài giây. So với 4G LTE, số lượng thiết bị được kết nối sẽ nhiều hơn tới 100 lần trên mỗi đơn vị diện tích.

Việc làm iot lương cao hấp dẫn tại Topdev.vn

Vậy làm cách nào mà 5G có thể mở rộng platform IoT? Bên trong, IoT có rất nhiều thiết bị thu thập dữ liệu trong khoảng thời gian thực trong khoảng cụ thể. Tuy nhiên, việc trao đổi dữ liệu không ngừng sẽ gây ảnh hưởng ít nhiều tới thời lượng pin của các thiết bị. Công nghệ mạng không dây đời mới này sẽ giảm đến 90% mức sử dụng năng lượng mạng và với các thiết bị IoT năng lượng thấp, thời lượng pin sẽ được duy trì đến 10 năm.

Trước mắt vẫn còn là chặng đường dài trước khi 5G dẫn đầu xu hướng, tuy nhiên các doanh nghiệp ngay từ bây giờ nên bắt đầu phát triển và mô phỏng các dịch vụ cũng như sản phẩm của mình để tận dụng khả năng vượt trội của 5G. Cùng điểm qua vài ngành công nghiệp có thể bị gián đoạn bởi 5G và IoT:

1) Xe oto tự lái:

Các cảm biến trên xe tự lái tạo ra số lượng lớn dữ liệu, nhiệt độ, điều kiện giao thông, thời tiết, vị trí GPS, …. Việc sản xuất và cảm biến lượng dữ liệu khổng lồ như vậy sẽ tiêu tốn khá nhiều năng lượng. Xe tự lái đồng thời lệ thuộc rất nhiều vào việc truyền tải thông tin theo thời gian thực để đáp ứng một cách tốt nhất. Tuy nhiên, với khả năng kết nối tốc độ cao và độ trì hoãn (latency) thấp, những dòng xe thông minh này sẽ liên tục thu thập tất cả các loại dữ liệu, bao gồm cả những data rất quan trọng về thời gian mà thuật toán tự hoạt động để theo dõi tình trạng hoạt động của xe và cải thiện thiết kế trong tương lai.

2) Chăm sóc sức khỏe:

Lĩnh vực y tế cũng sẽ được cải thiện khi tất cả các thiết bị y tế đều được tích hợp IoT. Khu vực nông thôn hay các khu vực vùng xa chưa có trang thiết bị y tế tân tiến sẽ tận dụng được ưu điểm IoT. Với độ trễ thấp như vậy, những dịch vụ y tế đòi hỏi sự chính xác cao như phẫu thuật đều có khả năng thực hiện từ xa.

3) Logistics:

Kết nối 5G sẽ giúp sensor cảm biến IoT hoạt động liên tục. Không chỉ có tốc độ cao và độ trễ thấp giúp thu thập data trong thời gian thật, mà hiệu quả năng lượng cũng có thể tích luỹ dữ liệu có tính chất đa dạng tại các điểm trong chuỗi cung ứng trong khoảng thời gian dài. Người tiêu dùng có thể cập nhật những thông tin chi tiết nhất, như món cá họ vừa mua được đánh bắt tại vùng nước nào, nhiệt độ trữ lạnh thực phẩm trong quá trình vận chuyển ra sao và được giao tới tay người bán khi nào.

smart city 5G

4) Thành phố thông minh:

5G cho phép các ứng dụng phổ biến rộng rãi hơn từ xử lý nước và chất thải, giám sát giao thông đến các cơ sở chăm sóc sức khoẻ nâng cao. Thành phố thông minh tận dụng lợi ích từ mạng thế hệ mới khi ngày càng có nhiều sensor xâm nhập vào cơ sở hạ tầng thành phố. 5G không chỉ có khả năng xử lý data khổng lồ mà còn giúp tích hợp nhiều hệ thống khác nhau, liên tục truyền thông tin với nhau để toàn bộ thành phố được kết nối và “xích lại gần nhau”.

5) Hệ thống bán lẻ:

IoT sẽ nhận ảnh hưởng tích cực từ sự ra đời của 5G khi các nhà bán lẻ có thể nhận được sự tham gia trải nghiệm của khách hàng qua smartphone. Chất lượng kết nối tốt hơn cùng với sự gia tăng số lượng thiết bị giúp họ tương tác với người tiêu dùng nhanh hơn với bảng chỉ dẫn digital. Các cách thức tương tác khách hàng mới mẻ và sáng tạo kết hợp với Augmented Reality và Virtual Reality sẽ trở nên phổ biến hơn. Nhà bán lẻ có thể nâng cao trải nghiệm mua sắm thông qua các hoạt động bán lẻ ở nhiều kênh một cách hiệu quả.

Nếu số lượng thiết bị kết nối phần cứng lên tới hàng tỷ thì tiềm năng cho các sản phẩm tiêu dùng có identical twins sẽ nhiều hơn đáng kể. Các sản phẩm tiêu dùng không cần thiết phải kết nối Internet thường xuyên như các thiết bị phần cứng nhưng có thể gửi và nhận thông tin khi kết nối với các sản phẩm thông minh dựa trên tương tác người tiêu dùng và các thực thể khác thông qua scan, RFID, NFC, … cơ sở hạ tầng wireless hiện tại không thể dựa trên task quản lý số lượng lớn sản phẩm online, nhưng 5G sẽ biến điều đó thành khả thi. Đóng gói thông minh (Smart Packaging) và nhãn kỹ thuật số (Digital Labels) sẽ thay đổi cách quản lý hàng tồn kho và theo dõi logistics cũng như cung cấp phương tiện tương tác với người tiêu dùng.

“5G và IoT cùng đưa mọi mặt hàng lên kệ trên Internet bằng cách tạo ra cặp song sinh kỹ thuật số (digital twins)”

4G không đủ khả năng xử lý dữ liệu khi số lượng sensor và các thiết bị online ngày càng tăng, hạn chế khả năng IoT. 5G với tốc độ truyền tải dữ liệu cao, độ trễ thấp, linh hoạt hơn cùng với sự tiêu thụ năng lượng thấp, tiết kiệm chi phí và khả năng hỗ trợ số lượng lớn các thiết bị, sẽ là công cụ hoàn hảo cho IoT. Trong tương lai, không chỉ smartphone, máy tính hay máy tính bảng mới được liên kết Internet mà là hàng loạt các vật dụng hàng ngày, sản phẩm tạp hoá. Điều này hứa hẹn mang đến các cơ hội cho các tổ chức cung cấp dịch vụ và ứng dụng để quản lý các hệ IoT phức tạp và chuyển đổi dữ liệu thành sự hiểu biết thông minh (smart insights). 5G sẽ đóng vai trò quan trọng trong việc chuyển đổi không chỉ cách chúng ta giao tiếp mà ảnh hưởng lên cả doanh nghiệp và toàn xã hội.

Khá nhiều điều thú vị về lĩnh vực IoT trong thế giới 5G mà chúng ta cần khám phá, bạn đừng bỏ lỡ những update mới nhất tại Vietnam Mobile Day năm thứ 9 đánh dấu sự trở lại của hội nghị công nghệ lớn nhất hằng năm.

(Techtalk via ecnmag)

🔥🔥🔥 Những slots EARLY BIRD cuối cùng đang được săn đón, đừng bỏ qua cơ hội hấp dẫn này nhé. Nhập ngay code: EARLYBIRD@VMD2021 để giảm ngay 100.000đ/vé. Chuẩn bị bùng nổ tại #VMD2021 nào! 

OAuth2 là gì? Tìm hiểu về OAuth2

oauth2-la-gi

OAuth2 là gì?

OAuth2 là gì? – Nó là viết tắt của Open với Authentication hoặc Authorization. OAuth ra đời nhằm giải quyết vấn đề trên và xa hơn nữa, đây là một phương thức chứng thực giúp các ứng dụng có thể chia sẻ tài nguyên với nhau mà không cần chia sẻ thông tin username và password.

Ứng dụng

  • Authentication: xác thực người dùng.
  • Authorization: người dùng ủy quyền cho ứng dụng truy cập tài nguyên của họ.

Nếu bạn thấy một website (hay phần mềm) nào đó cho phép đăng nhập bằng tài khoản Facebook hay Google mà không cần tạo nick mới thì đó chính là OAuth.

Thực tế, mỗi người trong chúng ta đã từng có hàng vài chục tài khoản ở các website khác nhau đến nỗi phải đặt các tài khoản này giống hệt nhau.

  Code nhanh và hiệu quả hơn với VSCode tips, tricks

  Những Plugin không thể thiếu cho VSCode

Quá trình phát triển

  • Năm 2006, Twitter đưa ra chuẩn OAuth đầu tiên có tên là OpenID, điểm yếu đó là yêu cầu người dùng phải cung cấp thông tin cá nhân (username + password).
  • Năm 2010, phát hành phiên bản chính thức đầu tiên của Oauth 1.0 (RFC 5849).
  • Sau đó lỗi bảo mật nghiêm trọng được phát hiện với tên gọi Session Fixation cho phép Hacker chiếm quyền truy cập vào tài nguyên của người dùng.
  • Năm 2012, OAuth2 ra đời, tuy vẫn còn những lỗi bảo mật như dùng Chrome để Hack Facebook nhưng hiện vẫn đang được sử dụng khá rộng rãi.

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

Khi bạn đăng nhập bằng Facebook hay Gmail, website sẽ dẫn bạn đến trang (hoặc phần mềm) Facebook và liệt kê những quyền mà nó cần phải có để cho phép bạn đăng nhập và sử dụng dịch vụ.

Nếu bạn đồng ý thì lúc này Facebook sẽ phát cho website một cái token Token này chứa một số quyền hạn nhất định giúp cho website có thể xác minh bạn là ai cũng như giúp cho website có thể hoạt động được.

Nếu website này bị hacker tấn công thì nó chỉ lấy được thông tin hay hoạt động của bạn trên website đó mà không ảnh hưởng đến những website khác mà bạn đang sử dụng.

Do đó cách đăng nhập bằng phương thức OAuth này rất an toàn cho người dùng cuối như chúng ta.

Sơ đồ luồng hoạt động của OAuth2

  Học lập trình thế nào để không thất nghiệp?

  Lập trình đâu chỉ có những dòng code

  Liệu tôi có làm Junior Developer "mãn kiếp"?
  1. Ứng dụng (website hoặc mobile app) yêu cầu ủy quyền để truy cập vào Resource Server (Gmail,Facebook, Twitter hay Github…) thông qua User
  2. Nếu User ủy quyền cho yêu cầu trên, Ứng dụng sẽ nhận được ủy quyền từ phía User (dưới dạng một token string)
  3. Ứng dụng gửi thông tin định danh (ID) của mình kèm theo ủy quyền của User tới Authorization Server
  4. Nếu thông tin định danh được xác thực và ủy quyền hợp lệ, Authorization Server sẽ trả về cho Ứng dụng access_token. Đến đây quá trình ủy quyền hoàn tất.
  5. Để truy cập vào tài nguyên (resource) từ Resource Server và lấy thông tin, Ứng dụng sẽ phải đưa ra access_token để xác thực.
  6. Nếu access_token hợp lệ, Resource Server sẽ trả về dữ liệu của tài nguyên đã được yêu cầu cho Ứng dụng.

oauth2 là gì

Tổng kết oauth2 là gì

Luồng hoạt động thực tế có thể sẽ khác nhau tùy thuộc vào việc ứng dụng sử dụng loại ủy quyền (authorization grant type) nào, trên đây chỉ là ý tưởng chung để thực hiện.

Bài viết sẽ không đi sâu vào vấn đề làm thế nào để bạn có thể triển khai hệ thống OAuth trên Server của bạn mà chỉ giới thiệu thêm về luồng hoạt động của OAuth cũng như những việc cần làm khi ứng dụng của bạn phải triển khai chức năng.

Để thực hiện chi tiết bạn tìm kiếm thêm trên Google để xem cách triển khai cho từng framework hay ngôn ngữ mà sản phẩm của mình đang làm nhé.

Có thể bạn muốn xem thêm:

Xem thêm tuyển dụng ngành cntt hấp dẫn tại TopDev!

Làm kỹ sư AI, mức lương 500 triệu là bình thường

Thị trường lao động riêng ngành lập trình sẽ cần 350.000 nhân lực đến trước cuối năm 2021 trong khi với khả năng hiện tại chỉ có khoảng 200.000 lao động đáp ứng được nhu cầu công việc.

Trong khi đó, giai đoạn 5 năm gần đây thì công nghệ AI (trí tuệ nhân tạo) được nhiều chuyên gia trong ngành đánh giá đã đạt mức hoàn thiện sau một quãng thời gian phát triển nhất định. Riêng tại thị trường Việt Nam, hiện có rất nhiều startup lớn nhỏ đang phát triển các dự án tiềm năng liên quan đến trực tiếp đến AI và Machine Learning tạo được nhiều giá trị đột biến cho toàn ngành công nghệ nói chung. Cũng chính vì sự phát triển này mà mức lương cũng như độ nóng của kỹ sư AI được dự báo sẽ tăng mạnh trong những năm sắp tới.

Ở những kỳ hội thảo công nghệ thường niên như Vietnam Web Summit và Vietnam Mobile Day gần đây, rất nhiều doanh nghiệp đã đề cập đến các xu hướng đổi mới sáng tạo, trải dài từ trí tuệ nhân tạo đến tối ưu trí tuệ doanh nghiệp (Business Intelligence). Từ đó, chúng tôi đã đúc kết được một vài điểm nổi bật nhất cho thị trường việc làm IT trong năm nay.

Theo nhiều báo cáo thị trường gần đây cho thấy, năm 2018 sẽ là năm phát triển mạnh mẽ nhất cho các công nghệ ứng dụng trí tuệ nhân tạo (AI) và khối chuỗi (Blockchain) vào thực tiễn cuộc sống. Mở ra một kỷ nguyên mới với hàng ngàn cơ hội hấp dẫn cho tất cả các doanh nghiệp tại Việt Nam. Có thể nói, xu hướng tối ưu hoá trí tuệ doanh nghiệp cùng xu hướng AI đang dần vượt trội so với công nghệ blockchain.

Thực tế cho thấy, với những làn sóng đầu tư và phát triển tại Việt Nam trong những năm qua, các “ông lớn” trong nước như FPT, Viettel, VNG… đều đã bắt đầu nghiên cứu và cho ra đời nhiều giải pháp, ý tưởng phát triển sản phẩm ứng dụng AI vào thực tế cuộc sống. Không chỉ những công ty lớn, hàng trăm các startup cũng đã và đang ứng dụng những công nghệ này trực tiếp vào sản phẩm của mình. Có thể kể đến những cái tên như EyeQ, Cinnamon AI Labs,… Đây là một dấu hiệu rõ ràng nhất cho một xu hướng công nghệ mạnh mẽ, một làn sóng mới tại Việt Nam trong thời gian tới.

Thiếu hụt nhân sự, AI Engineer đạt mức lương cao nhất!

Với sự thay đổi chóng mặt của thị trường, TopDev – nền tảng tuyển dụng IT hàng đầu thuộc Công ty Cổ phần Applancer vừa phát hành “Báo cáo thị trường IT và tình hình nhân lực IT Việt Nam” Quý 4 – 2018 với thông tin được thu thập từ hơn 100.000 dữ liệu việc làm trong năm 2018 và có trên 15.000 ứng viên tham gia, đã đúc kết được nhiều góc nhìn thú vị cho thị trường IT trong năm nay cũng như dự đoán những xu hướng mới cho năm 2019.

Thiếu hụt nhân sự luôn là một bài toán nan giải cho thị trường IT, dù xu hướng lương và phúc lợi đang tăng mạnh cho ngành này, nhưng nhiều chuyên gia dự báo năm 2019 Việt Nam vẫn sẽ thiếu hụt từ 70.000 đến 90.000 nhân sự IT.

Theo báo cáo của TopDev, 5 ngôn ngữ lập trình được trả lương cao nhất chính là Python, .NET, PHP, JAVA và C++, trong đó, C++ vẫn đứng đầu với mức lương lên đến 27.600.000 triệu đồng/tháng ($1,185). Ở những lập trình viên làm việc tại TP.HCM sẽ thường có mức thu nhập cao hơn so với những khu vực khác.

Tính lương chuẩn với công cụ tính lương gross – net tại TopDev

Ngoài ra, khảo sát của TopDev cũng chỉ ra rằng, có đến 33.9% lập trình viên hướng tới việc phát triển những công nghệ chuyên sâu, 25% lập trình viên mong muốn hướng tới cấp quản lý. Trong đó, có đến 53% đang hài lòng với công việc của mình, 59.8% đang không có nhu cầu đổi việc. Vì vậy việc tuyển dụng ở các công ty sẽ trở nên khó khăn hơn trong năm 2019, đặc biệt là ở những vị trí cao cấp như Project Manager, dù mức lương có lên đến gần 40 triệu/tháng ($1,563).

Đặc biệt hơn cả, với xu hướng tăng mạnh của việc ứng dụng trí tuệ doanh nghiệp và ứng dụng AI vào các sản phẩm trong thời gian gần đây tuy nhiên thị trường IT vẫn chưa bắt nhịp kịp và dần trở nên khan hiếm các kỹ sư làm công nghệ này. Dù mức lương “khủng” lên đến 500 triệu/năm ($22.000) nhưng nhiều doanh nghiệp vẫn phải đang loay hoay trong việc tìm kiếm các ứng viên phù hợp. Đa phần họ sẽ phải đào tạo từ chính những nhân viên lâu năm đang làm việc tại các dự án có liên quan đến công nghệ này.

Mặc dù tuyển dụng khó khăn, nhưng nhiều doanh nghiệp vẫn phụ thuộc lớn vào các nguồn tuyển dụng không chính thống và thông qua các mối quan hệ cá nhân của mình. Báo cáo chỉ ra rằng, có đến 58% các nhà tuyển dụng tìm kiếm ứng viên qua các kênh giới thiệu nội bộ (referral), và chỉ có 51% các nhà tuyển dụng chọn đăng tin tìm kiếm qua các kênh chính thống.

Sự phát triển nhanh chóng của nhiều xu hướng công nghệ mới trong năm 2018-2019 mở ra nhiều cơ hội tốt hơn cho các lập trình viên tại Việt Nam, tuy nhiên cũng sẽ gây không ít trở ngại cho nhà tuyển dụng nếu không biết tuyển dụng đúng cách.

Hiện đã có rất nhiều doanh nghiệp đang hướng đến những phương pháp tuyển dụng mới với tầm nhìn dài hạn hơn như làm thương hiệu doanh nghiệp (Employer Branding), nhằm tạo sự ảnh hưởng và lan tỏa hình ảnh của mình của mình đến những ứng viên tốt nhất trong cộng đồng lập trình, thay vì chỉ đăng job tuyển dụng hoặc thông qua các kênh nội bộ như trước đây.

Bên cạnh đó, trong các xu hướng công nghệ năm nay, các chuyên gia đưa ra dự đoán rằng AI sẽ thay thế 16% công việc con người trong thập kỷ tới.

Download toàn bộ báo cáo tại đây

TopDev

Liệu tôi có làm Junior Developer “mãn kiếp”?

Liệu tôi có làm Junior Developer mãn kiếp?

Đừng tự chôn vùi khả năng của bạn

Nghiêm túc mà nói, đừng mãi là một junior developer. Junior developer để chức danh của họ trong CV, email, và LinkedIn … Họ tự tin nói cho cả thế giới biết điều đó. Nhưng nó không đáng tự hào như bạn nghĩ đâu!

Khi bạn làm điều đó, đây là những gì nhà tuyển dụng và các công ty sẽ nghĩ về bạn: ” Xin chào, tôi đang tìm kiếm một công việc với vị trí developer. Tôi vẫn là người mới, nhưng ông có tin tưởng tôi một lần! và tin tưởng rằng tôi sẽ trở thành tài sản chứ không phải là gánh nặng của công ty ông ? Oh, và tôi cũng sẽ cần rất nhiều sự giúp đỡ từ nhân viên của ông trong 6 tháng đầu! “

Nhưng, tôi là một junior developer…! Nếu đúng như vậy, bạn sẽ thành công về lâu về dài hơn nếu bạn tập trung nâng cao kĩ năng để trở thành một intermediate developer. Đến lúc đó, bạn đã có thể bắt đầu nộp đơn xin việc. Hãy dành toàn bộ thời gian của bạn để học các kĩ năng cần thiết. Bằng cách này, bạn sẽ không còn tự gò bó bản thân với chức danh “ junior “ developer. Hãy nhớ rằng, ấn tượng đầu tiên rất quan trọng. Khi được tuyển dụng vào vị trí junior developer, bạn sẽ mất nhiều thời gian hơn để thăng tiến, thay vào đó bạn có thể dành một chút thời gian tự chuẩn bị cho bản thân và tự xem mình là intermediate developer, và bạn có thể sẽ được tuyển dụng vào những vị trí tốt hơn rất nhiều.

  Junior developer là gì? Những quy tắc bất biến giành cho Junior developer

Nhưng khi nào tôi mới biết tôi không còn là một junior developer ? … Bạn sẽ không biết được đâu. Bạn sẽ luôn cảm thấy không bao giờ biết đủ nhiều. Bạn sẽ luôn cảm thấy người khác thông minh hơn bạn. Đây được gọi là hội chứng của bệnh nhân nhồi máu cơ tim. Nó rất bình thường và mọi developer đều có cảm giác đó. Nhưng sau đây là một bài kiểm tra đơn giản dành cho các web developer: Bạn có thể giải thích cho các thành viên trong gia đình bạn cách hoạt động của internet? Một máy tính hoạt động như thế nào ? Trang web hoạt động như thế nào? Bạn có hiểu biết cơ bản về HTML, CSS và Javascript để có thể xây dựng trang web của riêng bạn không? Bạn có biết gì về React không? Bạn đã tự xây dựng một vài dự án trên GitHub lần nào chưa? Và bạn có cảm thấy thoải mái khi đưa trang web và ứng dụng của bạn lên online không ?

Tốt, bạn không còn là một junior developer nữa.

Nhưng bây giờ tôi cần một công việc ngay! … Hãy ngừng suy nghĩ ngắn hạn. Trừ khi bạn có cơ hội làm việc với những người thực sự thông minh mà bạn có thể học hỏi mỗi ngày, hay làm việc với các công nghệ mới ( chỉ có vài vị trí dành cho junior developer cho bạn cơ hội tiếp cận điều này), bạn nên dành nhiều thời gian hơn để học hỏi các kỹ năng, thoát khoải tư duy của một junior. Về lâu về dài, bạn sẽ kiếm được nhiều tiền hơn, có cơ hội làm việc với đội ngũ phát triển giỏi hơn, và bạn sẽ có nhiều khả năng làm việc cho một công ty cho bạn nhiều cơ hội và tiếp xúc với các công nghệ hiện đại hàng đầu hơn. Đừng tiếp tục làm việc với WordPress plugin trong vị trí junior developer của một công ty luật. Điều đó sẽ không có lợi bạn về lâu về dài.

  7 sự thật mình bỏ lỡ khi còn là lập trình viên junior

Nếu bạn nộp đơn cho vị trí junior developer, trường hợp hoàn hảo nhất có thể xảy ra là: Bạn sẽ trở thành một junior developer.

Nếu bạn nộp đơn cho vị trí intermediate developer, trường hợp hoàn hảo nhất có thể xảy ra là: Bạn sẽ trở thành một intermediate developer.

Đừng tự chôn vùi khả năng của bạn

OK, ông nói hay lắm Andrei, nhưng tôi vẫn không biết phải làm gì. Tôi vẫn chỉ là một junior developer …! 

Trước tiên, hãy ngừng xem bản thân là một junior developer. Vẫn giữ suy nghĩ của một junior developer khi học từ người khác, nhưng đừng bao giờ hài lòng ở vị trí junior developer. Nộp đơn vào vị trí bạn chưa đủ điều kiện không có nghĩa là bạn đang “ được voi đòi tiên “. Hãy nhớ rằng: nếu bạn không hỏi, câu trả lời sẽ luôn là không.

Đừng quá đề cao thế giới và đánh giá thấp bản thân. Bạn giỏi hơn bạn nghĩ đấy!

Tìm việc làm junior IT lương cao trên TopDev

WebRTC là gì? Phương thức hoạt động và Ứng dụng

WebRTC là gì? Tại sao WebRTC lại được ứng dụng nhiều trong giới lập trình hiện nay? Là viết tắt của Web Real-Time Communication, ta có thể hiểu được đây là một công cụ hỗ trợ người dùng tương tác, trò chuyện trực tiếp trên website. Để tiếp tục hiểu thêm về WebRTC, cùng TopDev đọc tiếp bài viết dưới đây bạn nhé!

WebRTC là gì?

WebRTC là gì? Phương thức hoạt động và Ứng dụng
WebRTC là gì? Phương thức hoạt động và Ứng dụng

WebRTC (Web Real-Time Communication) là một tập hợp các hàm lập trình (web API) được phát triển bởi World Wide Web Consortium (W3C). Khả năng hỗ trợ trình duyệt giao tiếp với nhau theo thời gian thực bằng video, âm thanh hay truyền tải dữ liệu “Peer-to-Peer” (P2P) mà không cần browser phải cài thêm plugins hay phần mềm hỗ trợ nào từ bên ngoài. WebRTC có thể giúp chúng ta gọi điện video ngay trong trình duyệt mà không cần đăng kí tài khoản, ngoài ra chúng còn được xài để phát triển game chơi trực tiếp trong trình duyệt và rất nhiều loại ứng dụng khác.

Cách webRTC hoạt động

Cách webRTC hoạt động
Cách webRTC hoạt động

Kết nối Peer-to-Peer

Hầu hết các ứng dụng WebRTC dựa trên kiến trúc P2P (peer-to-peer). Trong kết nối P2P, các thành viên truyền dữ liệu trực tiếp với nhau mà không cần trung gian. Ngay cả khi một thành viên rời khỏi cuộc gọi, các thành viên còn lại vẫn có thể tiếp tục chia sẻ dữ liệu. Điều này làm cho WebRTC vượt trội so với các công nghệ truyền thông truyền thống, nơi người dùng không thể tiếp tục nếu mất kết nối với máy chủ. Ngoài ra, các peer thường gần nhau về mặt địa lý, giảm khoảng cách dữ liệu phải truyền tải.

Máy chủ Signaling

Máy chủ signaling giúp thiết lập kết nối ban đầu giữa các peer. Nó theo dõi các sự kiện như người dùng tham gia hoặc rời khỏi cuộc gọi. Máy chủ signaling cần thiết trong giai đoạn khởi tạo cuộc gọi nhưng không cần thiết trong quá trình giao tiếp liên tục. Tuy nhiên, nó có thể được sử dụng để theo dõi các sự kiện như một peer bị ngắt kết nối. Có nhiều cách để triển khai máy chủ signaling, yêu cầu duy nhất là làm cầu nối giữa các peer.

SDP (Session Description Protocol)

SDP giúp các peer trao đổi thông tin và thiết lập kết nối mà không cần biết chi tiết về hệ thống của nhau. SDP cung cấp thông tin về phần mềm, phần cứng và loại phương tiện mà peer muốn trao đổi. Khi khởi tạo kết nối, một peer đưa ra đề nghị (offer) và nhận lại câu trả lời (answer).

  • Offer/Answer: Khi khởi tạo kết nối, một peer đưa ra đề nghị và nhận lại câu trả lời.
  • ICE (Interactive Connectivity Establishment) candidates: Tìm kiếm các phương tiện giao tiếp tốt nhất cho các peer.
  • NAT (Network Address Translation): WebRTC phải vượt qua các lớp NAT để kết nối trực tiếp giữa các peer. WebRTC sử dụng các máy chủ TURN để kết nối các thiết bị qua NAT với internet công cộng, giúp truyền tải dữ liệu media giữa các trình duyệt.

WebRTC được thiết kế để thiết lập kết nối trực tiếp giữa các bên, nhưng lớp NAT có thể làm phức tạp quá trình này. Các ứng dụng WebRTC sử dụng máy chủ TURN để kết nối các máy trên NAT với mạng internet công cộng, đảm bảo truyền tải dữ liệu media giữa các trình duyệt.

Ứng dụng của webRTC

WebRTC (Web Real-Time Communication) là một công nghệ tiên tiến cho phép truyền tải âm thanh, video và dữ liệu trực tiếp giữa các trình duyệt và thiết bị mà không cần các plugin hoặc phần mềm bên ngoài. Dưới đây là các loại ứng dụng mà bạn có thể phát triển bằng WebRTC:

  • Ứng dụng Video Chat: Tạo cuộc gọi video một đối một hoặc nhóm như Skype, Google Meet, Zoom.
  • Ứng dụng Audio Chat: Thực hiện các cuộc gọi âm thanh qua internet như VoIP, Google Voice.
  • Truyền Hình Trực Tiếp: Phát trực tiếp sự kiện, hội nghị trên YouTube, Facebook Live.
  • Chia Sẻ Màn Hình: Hỗ trợ kỹ thuật từ xa, thuyết trình.
  • Ứng Dụng Học Trực Tuyến: Lớp học ảo, dạy kèm trực tuyến với video và âm thanh thời gian thực, chia sẻ tài liệu.
  • Ứng Dụng Chơi Game Nhiều Người Chơi: Truyền tải dữ liệu game giữa các người chơi.
  • Hệ Thống Giám Sát và An Ninh: Camera an ninh, giám sát từ xa.

WebRTC mang lại nhiều cơ hội phát triển các ứng dụng thời gian thực với khả năng truyền tải dữ liệu hiệu quả và bảo mật.

Demo – Viết ứng dụng gọi video giữa 2 người bằng Webrtc và Firebase

Tham khảo nguồn tại đây.

1.Cài đặt Firebase

Firebase là gì: Đó là một dịch vụ cơ sở dữ liệu thời gian thực hoạt động trên nền tảng đám mây được cung cấp bởi Google nhằm giúp các lập trình phát triển nhanh các ứng dụng bằng cách đơn giản hóa các thao tác với cơ sở dữ liệu.

Vào trang Firebase để đăng ký một tài khoản và chọn “Create New Project”. Sau khi tạo được project xong thì chọn “Add Firebase to your web app”, tại đây bạn sẽ có một đoạn mã Javascript có chứa key ứng dung.

<script>
  // Initialize Firebase
  // TODO: Replace with your project's customized code snippet
  var config = {
    apiKey: "<API_KEY>",
    authDomain: "<PROJECT_ID>.firebaseapp.com",
    databaseURL: "https://<DATABASE_NAME>.firebaseio.com",
    projectId: "<PROJECT_ID>",
    storageBucket: "<BUCKET>.appspot.com",
    messagingSenderId: "<SENDER_ID>",
  };
  firebase.initializeApp(config);
</script>

Trong phần Rules của database thay đổi giá trị .read và .write chuyển sang thành true

 

2.Đến phần Code

Code 1 giao diện html có thêm thẻ <video></video> để show camera:

<html>
     <head>
         <script src="https://www.gstatic.com/firebasejs/5.0.4/firebase.js"></script>
         <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
     </head>
     <body onload="showMyFace()">
         <video id="yourVideo" autoplay muted></video>
         <video id="friendsVideo" autoplay></video>
         <br />
         <button onclick="showFriendsFace()" type="button" class="btn btn-primary btn-lg"><span class="glyphicon glyphicon-facetime-video" aria-hidden="true"></span> Call</button>
     </body>
</html>

css:

video {
 background-color: #ddd;
 border-radius: 7px;
 margin: 10px 0px 0px 10px;
 width: 320px;
 height: 240px;
}
button {
 margin: 5px 0px 0px 10px !important;
 width: 654px;
}

Javascript

    1. Cấp quyền truy cập vào thư mục gốc của cơ sở dữ liệu Firebase
      var database = firebase.database().ref();
    2. Hàm sendMessage để thêm cơ sở dữ liệu vào Firebase: database.on('child_added', readMessage);
    3. Tạo yourId random: var yourId = Math.floor(Math.random()*1000000000);
    4. Khai báo máy chủ sử dụng: Hai máy chủ STUN sử dụng ở đây là của Google và Firefox, bạn cũng có thể thêm nhiều STUN khác tùy thích:
      var servers = {'iceServers': [
          {'urls': 'stun:stun.services.mozilla.com'},
          {'urls': 'stun:stun.l.google.com:19302'}
      ]};

      Note: STUN là gì? STUN (Session Traversal Utilities for NAT) là một giao thức mạng cho phép các máy khách tìm ra địa chỉ công khai của mình, loại NAT mà chúng đang đứng sau và cổng phía Internet được NAT gắn liền với cổng nội bộ nào đó. Thông tin này được sử dụng để thiết lập giao tiếp UDP giữa 2 host mà đều nằm sau NAT router. Giao thức STUN được định nghĩa trong RFC 5389.

    5. Tạo một object PeerConnection var pc = new RTCPeerConnection(servers);
    6. Chờ đợi đối tượng ICE Candidate được tạo trên máy tính của bạn:
      pc.onicecandidate = (event => event.candidate ? sendMessage(yourId, JSON.stringify({'ice': event.candidate})) : console.log('Sent All Ice') );

      Chức năng này sẽ được gọi nhiều lần, một lần cho mỗi ICE Candidate (khó dịch sang tiếng Việt nên để nguyên) được tạo ra. Khi một ICE Candidate được tạo ra thì hàm này sẽ biến object thành một chuỗi. Sau đó, nó gửi chuỗi này cho bạn bè của bạn thông qua Firebase. Máy tính bạn bè của bạn cũng sẽ thực hiện tương tự như trên.

      ICE (Interactive Communication Establishment) nôm na dễ hiểu là một giao thức được cùng để thiết lập phiên media dựa trên UDP đi qua NAT một cách nhanh nhất. ICE sẽ tìm đường tốt nhất để kết nối giữa các peer, nó thử tất cả khả năng có thể kết nối một cách song song và lựa chọn con đường hiệu quả nhất.

    7. Khi bạn và người nhận nhận được một ICE Candidate dưới dạng chuỗi được gửi từ Firebase, thì JSON.stringify sẽ chuyển đổi chuỗi trở lại thành đối tượng ICE Candidate.
    8. Chờ đợi cho các đối tượng Offer, Answer, ICE Candidates được gửi:pc.onaddstream = (event => friendsVideo.srcObject = event.stream);
    9. Event onaddstream được gọi và đặt friendsVideo.srcObject thành object MediaStream. Thao tác này sẽ hiển thị video người kia trên máy tính của bạn và ngược lại. friendsVideo được gọi đến từ HTML.
    10. Thêm dữ liệu vào Firebase bằng hàm sendMessage :
      function sendMessage(senderId, data) {
          var msg = database.push({ sender: senderId, message: data });
          msg.remove();
      }
    11. Thêm hàm show camera của mình showMyFace:
      function showMyFace() {
           navigator.mediaDevices.getUserMedia({audio:true, video:true})
               .then(stream => yourVideo.srcObject = stream)
               .then(stream => pc.addStream(stream));
      }

      Khi gọi hàm getUserMedia, trình duyệt sẽ yêu cầu quyền truy cập camera. Nó sẽ trả về một đối tượng MediaStream cái mà bạn có thể đặt bằng yourVideo.srcObject. Đoạn này có chức năng hiển thị mặt của bạn trên chính máy tính của bạn. Sau đó, ta cần thêm cùng một đối tượng MediaStream vào đối tượng PeerConnection của bạn. Trên máy tính đối phương thực hiện cuộc gọi cũng thực hiện tương tự. Hàm này được gọi ngay khi tải trang, vì vậy bạn sẽ thấy khuôn mặt của mình ngay khi load trang.

    12. Hàm showFriendsFace:
      function showFriendsFace() {
           pc.createOffer()
               .then(offer => pc.setLocalDescription(offer) )
               .then(() => sendMessage(yourId, JSON.stringify({'sdp': pc.localDescription})) );
      }

      Tạo đối tượng Offer bằng cách gọi pc.createOffer(). Đặt local description cho offer này bằng cách gọi pc.setLocalDescription(offer). Cuối cùng gửi đối tượng Offer cho bạn của bạn bằng cách gọi sendMessage.

    13. Hàm readMessage
      function readMessage(data) {
           var msg = JSON.parse(data.val().message);
           var sender = data.val().sender;
           if (sender != yourId) {
               if (msg.ice != undefined) {
                   pc.addIceCandidate(new RTCIceCandidate(msg.ice));
               } else if (msg.sdp.type == "offer") {
                   pc.setRemoteDescription(new RTCSessionDescription(msg.sdp))
                       .then(() => pc.createAnswer())
                       .then(answer => pc.setLocalDescription(answer))
                       .then(() => sendMessage(yourId, JSON.stringify({'sdp': pc.localDescription})));
               } else if (msg.sdp.type == "answer") {
                   pc.setRemoteDescription(new RTCSessionDescription(msg.sdp));
               }
           }
      };

      Người nhận cuộc gọi có thể đọc được tin nhắn thông qua hàm readMessage. Với kiểu tin nhắn là offer thì bạn đã gửi cho người nhận một đối tượng Offer mà bạn đã tạo. Người kia sẽ thiết lập mô tả từ xa (remote decription) của họ cho đối tượng Offer mà bạn đã gửi cho họ bằng cách gọi pc.setRemoteDescription(new RTCSessionDescription(msg.sdp)). Người nhận sẽ tạo một đối tượng Answer bằng cách gọi đến pc.createAnswer(). Hàm này trả về một đối tượng Answer mà bạn sẽ thiết lập ở mô tả local. Người nhận làm được điều này bằng cách gọi đến pc.setLocalDescription(answer). Sau đó, người nhận lấy đối tượng Answer và gửi nó cho bạn bằng cách gọi sendMessage.

      Bởi vì kiểu của tin nhắn bây giờ đã là answer nên đoạn sau sẽ thực hiện pc.setRemoteDescription(new RTCSessionDescription(msg.sdp));

    14.  Toàn bộ code trên:
      var config = {
          apiKey: "<API_KEY>",
          authDomain: "<PROJECT_ID>.firebaseapp.com",
          databaseURL: "https://<DATABASE_NAME>.firebaseio.com",
          projectId: "<PROJECT_ID>",
          storageBucket: "<BUCKET>.appspot.com",
          messagingSenderId: "<SENDER_ID>",
        };
        firebase.initializeApp(config);
      
      var database = firebase.database().ref();
      var yourVideo = document.getElementById("yourVideo");
      var friendsVideo = document.getElementById("friendsVideo");
      var yourId = Math.floor(Math.random()*1000000000);
      var servers = {'iceServers': [
          {'urls': 'stun:stun.services.mozilla.com'},
          {'urls': 'stun:stun.l.google.com:19302'}
      ]};
      var pc = new RTCPeerConnection(servers);
      pc.onicecandidate = (event => event.candidate?sendMessage(yourId, JSON.stringify({'ice': event.candidate})):console.log("Sent All Ice") );
      pc.onaddstream = (event => friendsVideo.srcObject = event.stream);
      
      function sendMessage(senderId, data) {
          var msg = database.push({ sender: senderId, message: data });
          msg.remove();
      }
      
      function readMessage(data) {
           var msg = JSON.parse(data.val().message);
           var sender = data.val().sender;
           if (sender != yourId) {
               if (msg.ice != undefined) {
                   pc.addIceCandidate(new RTCIceCandidate(msg.ice));
               } else if (msg.sdp.type == "offer") {
                   pc.setRemoteDescription(new RTCSessionDescription(msg.sdp))
                       .then(() => pc.createAnswer())
                       .then(answer => pc.setLocalDescription(answer))
                       .then(() => sendMessage(yourId, JSON.stringify({'sdp': pc.localDescription})));
               } else if (msg.sdp.type == "answer") {
                   pc.setRemoteDescription(new RTCSessionDescription(msg.sdp));
               }
           }
      };
      
      database.on('child_added', readMessage);
      
      function showMyFace() {
           navigator.mediaDevices.getUserMedia({audio:true, video:true})
               .then(stream => yourVideo.srcObject = stream)
               .then(stream => pc.addStream(stream));
      }
      
      function showFriendsFace() {
           pc.createOffer()
               .then(offer => pc.setLocalDescription(offer) )
               .then(() => sendMessage(yourId, JSON.stringify({'sdp': pc.localDescription})) );
      }
      

Tổng kết

Nói tóm lại, WebRTC có thể được sử dụng cho nhiều mục đích, từ việc truyền tải video, âm thanh cho đến gửi dữ liệu theo thời gian thực giữa hai hoặc nhiều thiết bị với nhau mà không nhất thiết phải đi qua server trung gian. Điều này giúp giảm độ trễ trong việc truyền tải, giảm độ phức tạp khi phát triển ứng dụng cũng như giảm chi phí vận hành (vì không phải trả tiền thuê server, tiền điện, tiền bảo dưỡng…), kéo theo đó giá bán dịch vụ nếu có thì cũng sẽ thấp hơn.

  Lập trình PHP và những câu hỏi thường gặp khi phỏng vấn