Home Blog Page 129

Tại sao phải giữ chân nhân viên?

giữ chân nhân viên
giữ chân nhân viên

Nhân viên được xem là nguồn nhân lực – “khối tài sản” quan trọng nhất của các tổ chức. Những sự kết nối tạo ra giá trị cho các doanh nghiệp bắt nguồn từ hiệu quả quản lý nguồn nhân lực. Từ đó, một vấn đề được đặt ra là liệu giữ chân nhân viên có thật sự quan trọng hay không? Và tại sao cần phải thực hiện điều đó? Cùng TopDev tìm hiểu thông qua bài viết sau.

Yếu tố con người chi phối, quyết định khả năng vận hành doanh nghiệp

giữ chân nhân viên

Có quá nhiều chiến lược nhằm đánh giá khả năng vận hành doanh nghiệp. Đồng thời cũng có rất nhiều yếu tố chi phối đến sự thành công của tổ chức. Chúng ta có thể kể đến như:

  • Xây dựng chiến lược Marketing hiệu quả;
  • Phát triển thương hiệu thông qua các sản phẩm được cải tiến về chất lượng;
  • Các dịch vụ hỗ trợ tuyệt vời;

Nếu là một freelancer it đang muốn tìm kiếm công việc, bạn có thể bị thu hút bởi những yếu tố trên trong quy trình tổ chức nhân sự.

Tuy nhiên, dường như mọi người đã quên đi một nhân tố quan trọng – nhân tố con người. 

Xem thêm: Phân tích con người – Chiến lược quan trọng trong ngành Nhân sự

Con người nhân sự là nhân tố rất quan trọng. Họ sẽ là người trực tiếp trải nghiệm và đưa ra những đánh giá khách quan nhất. Chính con người nhân sự cũng là các cá nhân lên kế hoạch phát triển chiến lược cho doanh nghiệp một cách hiệu quả nhất. Do chủ động tìm hiểu về thị trường, họ luôn nắm bắt nhanh chóng mọi thứ. Đó là lý do họ luôn thấu hiểu sự thay đổi về nhu cầu thị trường. Từ đó, dễ dàng hơn trong việc thiết lập một quy trình hoàn hảo. Đồng thời, đảm bảo mọi thứ được vận hành một cách tối ưu. 

Mặc dù việc tự động hóa, sử dụng các hệ thống điều khiển giúp giảm thiểu sự can thiệp của con người, rất hữu ích trong nhiều trường hợp, nhưng nó cũng không thể thay thế các tương tác của con người. 

Tính cạnh tranh luôn tồn tại, giữ chân nhân viên là điều tất yếu phải thực hiện

Sự cạnh tranh nhân viên diễn ra ở mọi quy mô doanh nghiệp. Nếu bạn vuột mất những cơ hội giữ chân nhân viên, họ có thể rơi vào những bến đỗ mới từ các công ty đối thủ. Các freelancer it dù không phải là official nhưng trong công tác tuyển freelancer it, công ty vẫn phải có chiến lược thiếp lập và xây dưng độ uy tín thông qua việc đồng hành và giữ chân. Giữ chân nhân viên rất không dễ dàng như bạn tưởng. Nó giống như bạn đang cố bảo vệ những bí mật thương mại của doanh nghiệp. Chúng là tài sản và cần được bảo vệ.

giữ chân nhân viên

Tuy nhiên, các nhà quản lý nhân sự cũng phải thật tỉnh táo trong các quyết định. Chỉ những nhân viên có tiềm năng phát triển mới có cơ hội được tạo điều kiện đồng hành. Nếu có nguồn nhân lực chất lượng, tố chất phù hợp thì đó là một lợi thế to lớn cho doanh nghiệp.

Tính cạnh tranh luôn tồn tại và nó dường như càng khốc liệt hơn khi thời đại ngày một phát triển hơn, con người cũng chuyên nghiệp hơn. Đặc biệt, trong thời đại số, tính cạnh tranh trên thị trường lao động rất mạnh mẽ. Nếu các nhà quản lý không thể giải quyết được bài toán về việc giữ chân nhân viên, đó sẽ là một sự thụt lùi đáng kể.

Câu chuyện nắm bắt được thị trường và tính cạnh tranh là điều cần quan tâm. Song, các nhà quản lý nhân sự cũng cần có những giải pháp thực tế. Điều này giúp tạo ra lợi thế khai mở tiềm năng thu hút nhân sự, góp phần xây dựng một lực lượng nhân viên vững mạnh.

Nhân viên cũng có “giá”

Liệu  có thể tính được giá trị cụ thể của một nhân viên dưới góc độ tài chính hay không? Đáp án là có và tất nhiên có. 

Hãy thử đặt ra câu hỏi và giải đáp nó bằng những hình dung.

Mất đi một sự đồng hành, doanh nghiệp sẽ mất đi những gì?

giữ chân nhân viên

  • Chi phí về tuyển dụng quảng cáo, freelancer it, phỏng vấn và sàng lọc một ứng viên mới.
  • Tiếp đến chính là chi phí để thiết lập lộ trình đào tạo một người mới: đào tạo và quản lý.
  • Năng suất có sự tác động khi một nhân viên mới sẽ mất từ 1-2 năm để đạt được hiệu suất làm việc như nhân tài cũ.
  • Các chi phí xử lý cho các rủi ro nhỏ có thể xảy ra trở nên nhiều hơn. Do đang thích nghi, họ khó nắm bắt kịp các vấn đề trọng tâm trong công việc.
  • Tạo ra sự tác động đến môi trường làm việc: Một ai đó rời đi, nhiều suy nghĩ sẽ được đặt ra. Điều này tạo ra sự nghi ngờ, tâm lý hoang mang xung quanh môi trường làm việc. 

Chi phí để thay thế một nhân viên là bao nhiêu?

Theo một nghiên cứu của CAP, chi phí trung bình để thay thế một nhân viên được diễn đạt như sau:

– 16% tiền lương hàng năm cho các công việc lương thấp (dưới 30.000 đô la/năm).

Ví dụ: chi phí để thay thế một nhân viên bán lẻ  10$/ giờ sẽ là 3,328$. 

– 20% tiền lương hàng năm cho các vị trí tầm trung (30.000 đến 50.000 đô/năm).

Ví dụ: chi phí để thay thế người quản lý $40.000 sẽ là $8.000.

– 213% tiền lương hàng năm cho các vị trí điều hành có trình độ học vấn cao.

Ví dụ: chi phí để thay thế một CEO 100 nghìn đô la là 213.000 đô la.

Lời kết

Mọi nhân viên đều có một vị trí, một cái “giá” riêng. Và việc bạn đánh mất đi một hay nhiều nhân viên tài năng là một sự thiệt thòi lớn. Giữ chân nhân viên là một việc hết sức quan trọng và cần được đầu tư đúng mức. Một doanh nghiệp có phát triển lâu dài được hay không là dựa vào một đội ngũ nhân viên chất lượng. Vì thế, hãy lập các kế hoạch giữ chân nhân viên của bạn nhé. Tất nhiên, kế hoạch đó chỉ dành cho những nhân viên thật sự xứng đáng với các giá trị mà họ đang sở hữu.


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

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

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

Sứ mệnh và thách thức cho các “anh hùng” công nghệ tại Viettel Cyber Security

Chính thức thành lập từ tháng 4 năm 2019, Viettel Cyber Security (Trung tâm An ninh mạng Viettel) đã không ngừng thể hiện sức mạnh, khẳng định vị thế đứng đầu trong việc đảm bảo an ninh trên không gian mạng Việt Nam. 

Khẳng định vị thế hàng đầu – Sức mạnh “niềm tin” lan tỏa

Khởi đầu với 6 nhân sự từ năm 2011, Công ty An ninh mạng Viettel đã phát triển thành một đơn vị lớn mạnh với hơn 200 nhân sự và chính thức trở thành công ty riêng biệt sau 8 năm với tên gọi Viettel Cyber Security.

Là đơn vị trực thuộc Tập đoàn Công nghiệp Viễn thông Quân đội, Viettel Cyber Security có vai trò quan trọng trong việc thực hiện các nghiên cứu chuyên sâu, phát triển giải pháp đảm bảo An toàn thông tin các hệ thống của Tập đoàn cũng như cung cấp những sản phẩm, dịch vụ chất lượng đến với khách hàng trong nước và quốc tế.

Trải qua nhiều năm vươn lên phát triển, Viettel Cyber Security đã chiếm được sự tín nhiệm của các đối tác về chất lượng và đó cũng chính là lời cam kết mà Viettel Cyber Security dành cho các khách hàng của công ty.

Được mệnh danh là “tấm lá chắn thép khổng lồ” của doanh nghiệp Việt trước những mối nguy hiểm trên không gian mạng, Viettel Cyber Security đã đem đến một sự tin tưởng gần như tuyệt đối với những con số ấn tượng:

  • Hàng chục nghìn máy chủ, thiết bị mạng và hàng triệu đường truyền, thuê bao di động được bảo vệ an toàn nhờ sự nghiên cứu, xây dựng hệ thống giám sát, phòng thủ toàn diện.
  • Hơn 25.000 cuộc tấn công an ninh mạng từ các hacker trên thế giới nhắm vào Viettel và các khách hàng mỗi năm được phát hiện và ngăn chặn mỗi năm.
  • Hơn 100 lỗ hổng bảo mật zero-day được tìm thấy bởi các chuyên gia an toàn thông tin Viettel Cyber Security.

Những con số này không chỉ thể hiện sự đảm bảo về an toàn thông tin, mà còn cho thấy sự đầu tư của Viettel Cyber Security về chất lượng của đội ngũ nhân sự – Một trong những yếu tố then chốt tạo nên tầm vóc của công ty. 

Đội ngũ nhân sự chất lượng – Niềm tự hào của Viettel Cyber Security

Cho đến nay đội ngũ chuyên gia an toàn thông tin tại Viettel Cyber Security vẫn không ngừng tìm tòi, trau dồi kinh nghiệm để cải thiện chất lượng các dịch vụ, giải pháp của công ty. Mọi cố gắng đã được công nhận bởi những danh hiệu danh giá, những giải thưởng ấn tượng giúp thương hiệu Viettel vươn tầm quốc tế:

  • Giải đồng IT World Awards 2017; 
  • Giải bạc Stevie Awards 2017; 
  • Giải thưởng cho “Sản phẩm an toàn thông tin chất lượng cao” được công nhận bởi VNISA;
  • Giải “Dịch vụ an toàn thông tin tiêu biểu”, “Sản phẩm An toàn thông tin mới xuất sắc” do VNISA trao tặng;
  • Đạt “Danh hiệu sao khuê 2020” do VINASA công nhận; 
  • Danh hiệu “Chìa khóa vàng” 2020 với 9 giải thưởng được trao cho các sản phẩm, dịch vụ an toàn thông tin;
  • Danh hiệu “Nhà cung cấp dịch vụ quản lý an ninh mạng tốt nhất Việt Nam – Vietnam Managed Security Service Provider of the Year” năm 2020 của giải thưởng Frost & Sullivan trong khu vực châu Á – Thái Bình Dương.

Với những thành tích và sản phẩm, dịch vụ xuất sắc của mình, Viettel Cyber Security xứng đáng là “Tấm lá chắn thép khổng lồ” của các doanh nghiệp Việt trước những rủi ro và thách thức trên không gian mạng, tạo sự tin tưởng của khách hàng và đối tác dành cho công ty.

Bí mật phía sau những thành tựu của Viettel Cyber Security

Không chỉ mang đến sự tin tưởng tuyệt đối cho đối tác và khách hàng, niềm tin còn được công ty gửi trao đến toàn bộ những con người đã đóng góp sức lực và trí tuệ để xây dựng thương hiệu Viettel Cyber Security như hôm nay.

Coi trọng giá trị con người, cũng vì thế mà mỗi thành viên trong tổ chức luôn được quan tâm bằng những chính sách đãi ngộ xứng đáng giúp thúc đẩy động lực làm việc đồng thời lan tỏa niềm đam mê.

Cùng khám phá ngay những điều tuyệt vời đang chờ đợi các tài năng công nghệ:

  • Mức thu nhập hấp dẫn và xứng đáng;
  • Các CLB giải trí đầy hấp dẫn: CLB bóng đá, bóng bàn, bi-a, vẽ tranh, e-sport, chạy bộ, đạp xe,…
  • Có thêm chế độ bảo hiểm tại Bệnh viện TW Quân đội 108 và chế độ tại khu khám chữa bệnh chuyên biệt dành riêng cho CBCNV Viettel và người thân;
  • Có cơ hội làm việc với các chuyên gia hàng đầu, kinh nghiệm lâu năm trong ngành ATTT (top 100 hacker Facebook, Microsoft,…);
  • Có cơ hội tham gia các hội thảo ATTT trong nước và thế giới (Singapore, Mỹ, Tây Ban Nha,…);
  • Tham gia môi trường làm việc trẻ trung, hiện đại, nhiều cơ hội phát triển sự nghiệp;
  • Các hoạt động ngoại khóa, thể thao, văn hóa giúp xả hơi sau những giờ làm việc vất vả;
  • Thời gian làm việc linh động, trang phục thoải mái cùng các sự kiện teambuilding hàng quý, 12 ngày nghỉ phép trong năm và 3 ngày nghỉ dưỡng với mức hỗ trợ 9 triệu/người.

Để đáp ứng nhu cầu mở rộng và phát triển của mình, công ty kỳ vọng đến năm 2021, quy mô lực lượng nhân sự An toàn Thông tin của Viettel Cyber Security sẽ lên đến con số 500 người.

Đặc biệt, Viettel Cyber Security hiện đang vẫy gọi các tài năng công nghệ gia nhập và “chinh chiến” với vị trí Test Engineer

Nếu bạn yêu thích lĩnh vực công nghệ và mong muốn trở thành một trong những “người hùng” đóng góp sức mình bảo vệ an toàn thông tin cho hàng triệu người dùng Việt Nam thì Viettel Cyber Security chính là sự lựa chọn tuyệt vời.

>>> Vậy bạn còn chần chờ chi không mau nhấn nút APPLY và kích hoạt cho sự nghiệp mới ngay hôm nay.

>>> Đồng hành cùng Viettel Cyber Security viết nên câu chuyện sự nghiệp mới đầy rực rỡ!

Tái cấu trúc mã nguồn

Tái cấu trúc mã nguồn

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

Khái niệm

Mỗi người có một khái niệm tái cấu trúc mã nguồn (code refactoring) khác nhau, và khi chuyển ngữ sang tiếng việt, thì việc tìm một thuật ngữ chính xác càng khó hơn. Ở đây tôi xin chuyển nghĩa từ refactoring thành tái cấu trúc và chọn định nghĩa của Martin Fowler:

Tái câu trúc là thay đổi ở cấu trúc bên trong mà không làm thay đổi hành vi với bên ngoài của hệ thống.

Tái cấu trúc là một quá trình cơ học, hình thức và trong nhiều trường hợp rất đơn giản để làm việc với mã của hệ thống đã tồn tại để chúng trở nên “tốt hơn”. Khái niệm “tốt hơn” là một khái niệm mang tính chủ quan, và không có nghĩa là luôn làm ứng dụng chạy nhanh hơn mà thường được hiểu là theo các kỹ thuật hướng đối tượng, tăng an toàn kiểu dữ liệu, cải thiện hiệu xuất , đễ đọc, dễ bảo trì và mở rộng.

  Các kĩ sư Pinterest đã xây dựng Progressive Web App như thế nào?
  10 trang web hàng đầu để tìm hiểu WordPress

Hiệu quả của tái cấu trúc

Sản xuất phần mềm sẽ không hiệu quả nếu như bạn không thể theo kịp thay đổi của thế giới. Nếu như chúng ta chỉ sản xuất ra các phần mềm trong một vài ngày thì đơn giản hơn rất nhiều. Nhưng trong thế giới này chúng ta có rất nhiều đối thủ cạnh tranh. Nên nếu bạn không tái cấu trúc phần mềm của mình, khi đối thủ có một số tính năng hữu ích mới mà bạn không cập nhật thì sản phẩm của bạn nhanh chóng bị lạc hậu. Bởi thế là một lập trình viên bạn phải đón nhận và hành động một cách thích hợp với những thay đổi. Và khi thực hiện tái cấu trúc mã là bạn đang làm điều đó.

Cải thiện thiết kế

Nếu không áp dụng tái cấu trúc khi phát triển ứng dụng, thì thiết kế sẽ ngày càng tồi đi. Vì khi phát triển ứng dụng thì ta sẽ ưu tiên cho các mục tiêu ngắn hạn (đặc biệt khi áp dụng các quy trình phát triển linh hoạt), nên mã ngày càng mất đi cấu trúc. Một trong những tên của vấn đề này gọi là technical debt (nợ kỹ thuật). Khi xảy ra vấn đề thì rất khó để quản lý và dễ bị tổn thương .Thế nên việc áp dụng tái cấu trúc sẽ giúp cho mã giữ được thiết kế tốt hơn là ưu điểm quan trọng.

Mã dễ đọc hơn

Khi lập trình là chúng ta đang giao tiếp với máy tính để yêu cầu chúng làm điều mình muốn. Nhưng còn có người khác tham gia vào quá trình này là các lập trình viên khác hay chính chúng ta trong tương lai. Chúng ta biết khi lập trình thường sẽ có người phải đọc để kiểm tra xem có vấn đề với mã đó không hoặc để mở rộng hệ thống.

Nhưng có một vấn đề là khi làm việc, lập trình viên thường không nghĩ tới những người đó trong tương lai. Vậy thì trong trường hợp này tái cấu trúc đóng vai quan trọng là giúp cải thiện thiết kế của hệ thống, từ đó cũng giúp đọc mã dễ hơn.

Lợi ích hệ quả

Từ những lợi ích cơ bản ở trên ta có thêm các lợi ích khác: do hệ thống hiện thời có một thiết kế tốt hơn và mã dễ hiểu hơn, từ đó thì việc mở rộng hệ thống dễ dàng hơn, khó bị tổn thương hơn, nên tốc độ phát triển hệ thống luôn được duy trì; mã và thiết kế dễ đọc hơn, từ đó giúp tìm ra lỗi dễ dàng hơn; vì những mục tiêu ngắn hạn lập trình viên có thể chấp nhận một lỗ hổng nào đó về công nghệ hay thiết kế mà hiện thời không gây ảnh hưởng gì tới hệ thống, nhưng khi hệ thống lớn dần thì những lỗ hổng này được tích tụ và làm cho hệ thống dễ bị tổn thương, thể nên việc tái cấu trúc giúp nhanh chóng sửa những lỗ hổng này.

Thời điểm thực hiện

Khi thêm một chức năng mới

Khi thêm một chức năng mới, ta phải đọc lại mã để hiểu. Như vậy nếu lúc này ta thực hiện việc tái cấu trúc, mã sẽ dễ hiểu hơn, cộng với đó là này ta cũng dễ dàng hiểu mã hơn vì mình là người đã đọc và thực hiện việc tái cấu trúc. Một lý do khác là khi thực hiện việc tái cấu trúc vào thời điểm này thì thiết kế của hệ thống sẽ tốt hơn, từ đó việc mở rộng cũng dễ dàng hơn.

Khi sửa lỗi

Khi sửa lỗi ta cũng phải đọc mã, và như vậy việc tái cấu trúc làm mã dễ đọc hơn, có cấu trúc rõ ràng hơn từ đó dễ dàng phát hiện lỗi là điều cần thiết. Và bởi thế nếu bạn được gán là người sửa một lỗi nào đó thì bạn cũng thường được gán là người phải tái cấu trúc mã.

Khi rà soát mã

Nhiều tổ chức thực hiện việc rà soát mã (code review). Rà soát mã giúp cho các lập trình viên giỏi truyền lại cho các lập trình viên ít kinh nghiệm hơn, giúp cho mọi người viết mã rõ ràng hơn. Mã có thể là rất rõ ràng với tác giả, nhưng với người khác thì có thể không, bởi thế rà soát mã sẽ làm cho nhiều người đọc mã hơn. Có nhiều người đọc mã thì mã phải dễ đọc hơn và có nhiều ý tường hơn được trao đổi giữa các thành viên trong nhóm hơn. Bởi thế khi bạn thực hiện rà soát bạn phải đọc mã. Lần đầu bạn đọc bạn bắt đầu hiểu mã. Lần tiếp theo bạn sẽ có nhiều ý tưởng hơn để tái cấu trúc mã, từ đó bạn có thể thực hiện việc tái cấu trúc.

Các “mã bẩn” thường gặp

Chúng ta đã biết cần thực hiện tái cấu trúc khi nào, nhưng có một câu hỏi khác là mã như thế nào thì cần tái cấu trúc? Khái niệm mã bẩn (code smell) là mã có thể sinh vấn đề một cách lâu dài, sẽ giúp ta phát hiện mã cần phải tái cấu trúc. Sau đâu chúng ta sẽ liệt kê một số loại mã bẩn thường gặp:

  • Mã lặp

    Là những đoạn mã xuất hiện nhiều hơn một lần trong một hoặc nhiều ứng dụng của một chủ thể. Đó là hệ quả của các hành động: sao chép mã; các chức năng tương tự được viết bởi các lập trình viên khác nhau. Hệ quả là mã trở nên dài hơn, khó hiểu hơn và khó bảo trì hơn.

    Ví dụ đoạn mã tính giá trị trung bình của một mảng số nguyên trên C

    [sourcecode language=”c”] extern int array1[];
    
    extern int array2[];
    
    int sum1 = 0;
    int sum2 = 0;
    int average1 = 0;
    int average2 = 0;
    
    for (int i = 0; i < 4; i++)
    {
    sum1 += array1[i];
    }
    average1 = sum1/4;
    
    for (int i = 0; i < 4; i++)
    {
    sum2 += array2[i];
    }
    average2 = sum2/4;
    
    [/sourcecode]

    Ta thấy hai vòng lặp for là giống nhau!

  • Hàm dài

    Hàm dài là quá phức tạp, có lượng mã lớn. Nên khó để hiểu, triển khai, bảo trì và tái sử dụng. Nên việc tách thành các hàm nhỏ hơn là điều cần thiết.

  • Lớp lớn

    Lớp lớn là lớp chứa quá nhiều thuộc tính và chức năng, thường là của nhiều lớp khác. Bởi thế cúng khó để đọc, bảo trì và tái sử dụng. Nên cần thực hiện các kỹ thuật cần thiết để phân bổ thành nhiều lớp khác nhau.

  • Hàm có nhiều tham số đầu vào

    Khi một hàm có nhiều tham số đầu vào sẽ gây khó khăn để đọc, dùng và thay đổi. Với các ngôn ngữ lập trình hướng đối tượng ta có thể nhóm các tham số có liên quan vào một đối tượng để giảm số lượng tham số đầu vào.

  • Tính năng không phải của lớp

    Là hiện tượng một phương thức không nên thuộc một lớp, nhưng do phương thức muốn sử dụng các dữ liệu của lớp đó nên lập trình viên đã gán phương thức cho lớp. Đây là một vi phạm trong lập trình hướng đối tượng. Ta cần trả phương thức đó về đúng đối tượng.

  • Lớp có quan hệ quá gần gũi

    Đó là hiện tượng hai lớp có thể truy xuất vào các thuột tính riêng tư của nhau một cách không cần thiết. Điều đó đẫn đến là chính các lớp đó hay lớp con của chúng có thể thay đổi các thuộc tính của lớp con lại một cách “vô thức”.

  • Lớp quá nhỏ

    Việc tạo, bảo trì và hiểu một lớp tốn tài nguyên. Vậy nếu lớp đó quá nhỏ thì ta nên xóa bỏ lớp đó đi.

  • Lệnh switch

    Một trong những dấu hiệu tốt của lập trình hướng đối tượng là việc không dùng lệnh switch. Vấn đề của lệnh switch chủ yếu là vấn đề lặp mã. Bạn thường gặp những lệnh switch để phân bổ các chức năng ở nhiều nơi khác nhau trong cùng một ứng dụng. Và mỗi khi bạn thêm một tính năng mới, bạn phải tìm ở tất cả các lệnh này để thay đổi.

  • Từ chối kế thừa

    Điều này xảy ra khi một lớp được thừa kế dữ liệu cũng như các tính năng của lớp cha, nhưng lại không cần phải dùng tới chúng. Chúng ta không thể cấm đoán điều, nhưng nếu điều này xảy ra thường dẫn tới vấn đề hiểu lầm và vấn đề.

  • Định danh quá dài hoặc quá ngăn

    Các định danh cần mô tả đủ ý nghĩa để mã dễ đọc hơn và tránh gây hiểu nhầm. Bởi thế các định danh quá ngẵn thường không mô tả hết ý nghĩa và gây ra nhầm lẫn. Nhưng các định danh quá dài cũng có vấn đề tương tự. Bởi thế trong trường hợp này chúng ta có thể viết tắt hay tìm định danh thay thế.

  • Dùng quá nhiều giá trị

    Nếu trong mã có nhiều giá trị thì khi cần phải thay đổi các giá trị đó vì một lý do nào đó (ví dụ thay đổi độ chính xác) thì bạn cần phải thay đổi ở nhiều nơi. Không chỉ thế mà không phải ai và lúc nào cũng nhớ những giá trị đó có ý nghĩa gì, nên làm cho mã trở nên khó đọc hơn. Trong trường hợp này bạn có thể thay bằng cách đặt tên cho các hằng.

    Các kỹ thuật tái cấu trúc cơ bản

    Các kỹ thuật tái cấu trúc được chia thành các nhóm tùy theo tiêu chí. Ở đây chúng ta sẽ chia theo mục đích.

    Trừu tượng hóa

    Chia nhỏ mã

    Chuẩn hóa mã

Kết luận

Cải tiển là công việc cần thiết và đem lại hiệu quả cao. Nhưng lượng các kỹ thuật mà ta áp dụng được cho dự án của mình thì rất nhiều và tốn kém thời gian. Trong bài viết này tôi không hy vọng sẽ trình bày được tất cả hay nhiều kỹ thuật mà chỉ là một số kỹ thuật căn bản nhất.

Tài liệu tham chiếu

Fowler, M., K. Beck, et al. (1999). Refactoring: Improving the Design of Existing Code.

Ritchie, P. “Refactoring with Microsoft Visual Studio 2010.”

(2011). from http://sourcemaking.com/refactoring.

Nguồn hanoiscrum.net

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

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

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Cơ bản về Class trong C++

Cơ bản về Class trong C++

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

Class là gì?

Class hay lớp là một mô tả trừu tượng (abstract) của nhóm các đối tượng (object) có cùng bản chất, ngược lại mỗi một đối tượng là một thể hiện cụ thể (instance) cho những mô tả trừu tượng đó. Một class trong C++ sẽ có các đặc điểm sau:

  • Một class bao gồm các thành phần dữ liệu (thuộc tính hay property) và các phương thức (hàm thành phần hay method).
  • Class thực chất là một kiểu dữ liệu do người lập trình định nghĩa.
  • Trong C++, từ khóa class sẽ chỉ điểm bắt đầu của một class sẽ được cài đặt.
  Factory Function vs. Class
  Các kiểu dữ liệu trong lập trình C/C++ (Data type)

Ví dụ về một class đơn giản, class Car. Một chiếc xe hơi vậy thì sẽ có chung những đặc điểm là đều có vô lăng, có bánh xe nhiều hơn 3, có động cơ… Đó là một class, một cái model hay mẫu mà người ta đã quy định là nếu đúng như vậy thì nó là xe hơi. Nhưng mà xe thì có thể có nhiều hãng khác nhau, BMW, Vinfast, Toyota… Thì mỗi hãng xe lại có những model xe khác nhau nhưng chúng đều là xe hơi. Vậy thì trong lập trình cũng vậy, class là quy định ra một mẫu, một cái model mà các thể hiện của nó (instance) hay đối tượng (object) phải tuân theo.

Khai báo class và sử dụng class

Cú pháp khai báo một class cơ bản trong C++ như sau:

class <ClassName> {
    <access_modifier>:
        <data_type> property;

        <return_type> <method_name>(arguments) {
            return <something_match_return_type>;
        }

        <_return_type> <_method_name>(_arguments);
};

<_return_type> <ClassName>::<_method_name>(_arguments) {
    return <something_match_return_type>;
}

Ví dụ một class cơ bản:

class Person {
    public:
        string firstName; // property
        string lastName;  // property
        int age;          // property

        void fullname() { // method
            cout << firstName << ' ' << lastName;
        }
};

Trở lại với ví dụ ở đầu bài viết, class ở đây là Car, vậy thì thuộc tính của nó chính là speed, HP,… còn phương thức chính là run, turn left, right, turn on the light…

Lưu ý: các thuộc tính có thể bị trùng tên với các tham số trong các phương thức, vậy nên chúng ta nên dùng this-> hoặc toán tử phân giải phạm vi (::), ví dụ:

class Person {
    public:
        string firstName;
        string lastName;
        int age;

        void fullname() {
            cout << this->firstName << ' ' << Person::lastName;
        }
};

Nói qua một chút về con trỏ this, con trỏ this đề cập đến thể hiện hay instance của class đó. Do đó, thông qua con trỏ this, ta có thể truy cập đến các thuộc tính hoặc phương thức thuộc class đó như trên ví dụ bên trên.

Đối với toán tử phạm vi :: dùng để xác định phương thức hoặc thuộc tính được gọi thuộc lớp nào. Như trong ví dụ trên là truy xuất thuộc tính lastName thuộc lớp Person. Nếu như gọi từ namespace hoặc emum thì toán tử :: được dùng để gọi thành viên của namepsace hoặc enum đó. Ngoài ra, toán tử phân giải phạm vi nếu không có tên lớp phía trước thì được dùng để gọi một biến bên ngoài scope. Ví dụ:

int x;
int main()
{
    int x = 2;
    ::x = 3; // x ở ngoài
    return 0;
}

Sự khác biệt giữa this và class khá rõ ràng, this (ám chỉ thể hiện của class đang sử dụng this) chỉ sử dụng được trong class, còn đối với toán tử :: có thể sử dụng được cả ở trong và ngoài class. Quá rõ ràng, nếu dùng this ở ngoài thì biết nó chỉ thằng nào đúng không! Bạn không thể thay ::x ở ví dụ trên thành this->x hay ->x được.

Cú pháp tạo object của một class và sử dụng các thuộc tính và phương thức:

// tạo một object
<className> <object>;
// gán giá trị cho thuộc tính của object
<object>.property = <value>;

// có thể sử dụng property như một biến thông thường
cout << <object>.property;
// có thể sử dụng method như một hàm thông thường
<object>.method();

Lưu ý: chỉ những thuộc tính và phương thức public thì mới có thể được sử dụng như cách trên. Ví dụ về cách sử dụng class:

Person person;
person.firstName = "Khiem";
person.lastName = "Le";
person.fullname(); // sẽ in ra màn hình là "Khiem Le"

Access modifiers & properties declaration

Access modifier là phạm vi truy cập của các thuộc tính và phương thức sẽ được khai báo bên dưới nó. Có 3 phạm vi truy cập trong C++ là public, private và protected.

  • Các thuộc tính và phương thức khai báo public thì có thể được truy cập trực tiếp thông qua instance của class đó. Các thuộc tính nên khai báo là public nếu bạn không có ràng buộc điều kiện trước khi gán (người dùng có thể thoải mái gán giá trị) hoặc bạn không cần xử lý trước khi trả về giá trị thuộc tính;
  • Đối với private thì chỉ có thể được truy cập gián tiếp qua các phương thức public (Getter và setter). Các thuộc tính private thường được sử dụng khi bạn không mong muốn người khác có thể tùy ý gán giá trị hoặc là bạn muốn xử lý trước khi trả về giá trị.
  • Đối với protected, các phương thức và thuộc tính chỉ có thể truy cập qua các class kế thừa nó hoặc chính nó (sẽ được nói kĩ hơn trong bài kế thừa C++).

Ví dụ của access modifier:

class MyClass
{
	public:
		int public_property;

	private:
		int _private_property;

	// protected sẽ được trình bày trong bài kế thừa và đa hình trong C++
};

Đối với quy cách đặt tên biến, bạn có thể sử dụng PascalCase, CammelCase… nhưng đối với các thuộc tính và phương thức private bạn nên đặt tên có dấu _ đầu. Ví dụ như _privateProp. Trong một số ngôn ngữ bật cao, thậm chí đã không còn từ khóa private mà thay vào đó sẽ chỉ là dấu _ trước tên biến (ví dụ như Dart).

Method declaration

Phương thức cũng giống như một hàm bình thường, bạn cũng có thể không trả về giá trị, có thể có hoặc không có tham số, có thể override hàm… Đối với các tham số truyền vào phương thức, bạn cũng có thể đặt tên trùng với thuộc tính của class, sử dụng kết hợp với toán tử :: và con trỏ this. Hoặc bạn có thể đặt tên khác với thuộc tính (thường thì sẽ thêm dấu _ trước tên tham số như là thuộc tính private vậy).

Đối với phương thức thì có hai cách định nghĩa thi hành: định nghĩa thi hành trong lúc định nghĩa class và định nghĩa thi hành bên ngoài class.

Định nghĩa thi hành bên trong class:

class Animal {
    public:
        string sound;

        void makeNoise() {
            cout << sound;
        }
};

Định nghĩa thi hành bên ngoài class:

class Animal {
    public:
        string sound;

        void makeNoise();
};

void Animal::makeNoise() {
    cout << sound;
}

Lưu ý: các phương thức không làm thay đổi giá trị thuộc tính của đối tượng thì nên có từ khóa “const” trước phần thân. Ví dụ:

class Animal {
    public:
        string sound;

        void makeNoise() const;
};

void Animal::makeNoise() const {
    cout << sound;
}

Getter & setter

Đối với thuộc tính private, ta không thể truy cập trực tiếp từ bên ngoài, vậy có cách nào để truy cập? Đây là lúc sử dụng phương thức. Các phương thức lấy giá trị của thuộc tính được gọi là getter, các phương thức gán giá trị cho thuộc tính được gọi là setter.

class MyClass {
    private:
        int _age;

    public:
        int getAge() {         // getter
            return _age;
        }

        void setAge(int age) { // setter
            _age = age;
        }
};

Việc sử dụng các thuộc tính private nhằm mục đích không cho người khác tùy ý thay đổi giá trị của thuộc tính đó, ngoài ra còn giúp bạn xử lý kết quả trước khi trả về cho người yêu cầu. Việc đó được thực hiện thông qua getter và setter. Ví dụ:

class MyClass {
    private:
        int _age;

    public:
        bool isOldEnough() {
            if (_age >= 18)
                return 1;
            return 0;
        }

        int getAge() {
            return _age;
        }

        void setAge(int age) {
            if (age < 18) {
                cout << "You are not old enough\n";
            } else {
                _age = age;
            }
        }
};

Lưu ý cách đặt tên getter và setter. Bạn nên đặt get vào trước tên getter và set vào trước tên setter như ví dụ bên trên của mình. Và cũng theo như phần lưu ý cuối mục “Method declaration” ở trên, các getter nên đặt là “const” bởi vì getter chỉ lấy giá trị chứ không thay đổi giá trị thuộc tính.

Constructor

Constructor hay hàm dựng là một hàm đặc biệt, nó sẽ được gọi ngay khi chúng ta khởi tạo một object. Vậy thì tại sao chúng ta lại cần có constructor?

Nếu bạn để ý ví dụ trên bạn sẽ thấy ta phải khởi tạo một object sau đó gán các property và sử dụng, việc này rất tốn thời gian. Constructor sẽ giúp chúng ta giải quyết việc này. Cú pháp khai báo một constructor giống với hàm nhưng không có kiểu dữ liệu trả về:

class MyClass {
  public:
    MyClass() { // constructor
      cout << "Hello World!";
    }
};

// sử dụng
MyClass object; // sẽ in ra màn hình "Hello World"

Lưu ý constructor phải được khai báo public. Công dụng chính của constructor chính là khởi gán các thuộc tính, vậy nên constructor thường được định nghĩa như sau:

class Person {
	public:
	    string firstName;
	    string lastName;
	    int age;

	    Person(string _firstName, string _lastName, int _age)
	    {
	        firstName = _firstName;
	        lastName = _lastName;
	        age = _age;
	    }

	    void fullname() {
			cout << firstName << ' ' << lastName;
	    }
};

Constructor cũng có thể định nghĩa thi hành bên ngoài class giống như phương thức vậy:

class Person {
	public:
	    string firstName;
	    string lastName;
	    int age;

	    Person(string _firstName, string _lastName, int _age);

	    void fullname() {
	        cout << firstName << ' ' << lastName;
	    }
};

Person::Person(string _firstName, string _lastName, int _age)
{
	firstName = _firstName;
	lastName = _lastName;
	age = _age;
}

Để khởi tạo một object thông qua constructor, ta làm như sau:

Person person("Khiem", "Le", 20);
person.fullname(); // Khiem Le

Như vậy chúng ta không cần phải set từng thuộc tính cho object đó mà khởi tạo trực tiếp qua constructor.

Destructor

Đối với một số ngôn ngữ lập trình khác có thể destructor không phổ biến, nhưng đối với C++, việc được quản lý bộ nhớ một cách hoàn toàn do người lập trình làm chủ thì destructor là vô cùng cần thiết. Hãy thử nghĩ xem, trong số thuộc tính của class bạn định nghĩa có một con trỏ, mảng động… và bạn không sử dụng desctructor thì sẽ như thế nào? Đương nhiên sẽ xảy ra chuyện rò rỉ bộ nhớ và điều này cực kì không tốt. Với destructor bạn có thể xóa con trỏ đi khi object được thu hồi hoặc bạn có thể gọi tường minh destructor.

Cách khai báo destructor cũng giống như đối với constructor nhưng có kí hiệu ~ phía trước:

class MyClass {
    public:
        MyClass() { // constructor
            cout << "Constructor is executed\n";
        }

        ~MyClass() { // destructor
            cout << "Constructor is executed\n";
        }
};

// Khởi tạo object
ClassName t; // gọi constructor không tường minh
// Gọi destructor tường minh
t.~MyClass();

Static member

Static member hay thành viên tĩnh trong class C++ cũng tương tự như với static variable (biến tĩnh) trong function. Đối với function, sau khi thực hiện xong khối lệnh và thoát thì biến tĩnh vẫn sẽ không mất đi. Đối với class, thành viên tĩnh sẽ là thuộc tính dùng chung cho tất cả các đối tượng của class đó, cho dù là không có đối tượng nào tồn tại. Tức là bạn có thể khai báo nhiều object, mỗi object các thuộc tính của nó đều khác nhau nhưng riêng static thì chỉ có một và static member tồn tại trong suốt chương trình cho dù có hay không có object nào của nó hay nói ngắn gọn là dùng chung một biến static.

Các thành viên tĩnh của class có thể được truy cập từ bất kì đối tượng nào của class đó hoặc thông qua toán tử phạm vi (::). Biến tĩnh cũng có phạm vi truy cập như một biến thông thường (public, private và protected). Để khai báo một biến tĩnh, ta thực hiện thêm từ khóa “static” vào trước kiểu dữ liệu, sau đó khởi tạo giá trị bên ngoài như sau:

class MyClass {
    public:
        static int count;
};

int MyClass::count = 0;

Bây giờ bạn có thể sử dụng biến tĩnh như cách đã trình bày bên trên:

cout << MyClass::count; // 0
MyClass::count++; // 1

Để thấy được sự “dùng chung” của static member, các bạn có thể xem ví dụ sau:

MyClass khiemle;
khiemle.count = 100;
cout << MyClass::count; // 100

Trong ví dụ trên rõ ràng là mình chỉ set thuộc tính của object khiemle thôi nhưng mà khi in biến count qua toán tử phạm vi thì vẫn được kết quả là 100. Nghĩa là tất cả các object đều dùng chung thuộc tính static đó. Bạn có thể đặt thuộc tính tĩnh là hằng như sau:

class MyClass {
    public:
        static const int count;
};

const int MyClass::count = 0;

Thuộc tính là const sẽ không được thay đổi trong suốt chương trình, do đó bạn có thể gán giá trị ngay khi khai báo như sau:

class MyClass {
    public:
        static const int count = 0;
};

//const int MyClass::count = 0; Không cần dòng này nữa

Lưu ý là đối với static member không phải là hằng bạn sẽ không gán giá trị như cách trên được:

class MyClass {
    public:
        static int count = 0; // không được phép
};

Tiếp theo là phương thức tĩnh. Phương thức tĩnh cũng giống như thuộc tính tĩnh, chúng ta có thể gọi trực tiếp qua toán tử phạm vi mà không cần một object nào của nó tồn tại cả.

class MyClass {
	public:
	    static void sayHello() {
	        cout << "Hello";
	    }
};

MyClass::sayHello(); // Hello

Lưu ý là các phương thức tĩnh sẽ chỉ truy cập được đến các biến tĩnh và phương thức tĩnh khác chứ không được truy cập thành viên khác ngoài static member.

class Person {
	public:
	    string firstName;
	    string lastName;

	    static void fullname() {
	        cout << firstName << ' ' << lastName; // không hợp lệ
	    }
};

Tổng kết

Qua bài viết này, mình đã giới thiệu cho các bạn về class, thuộc tính, phương thức và hàm dựng trong C++. Trong bài viết thì cách đặt tên hàm, biến có phần không thống nhất với nhau, bạn nên chọn một cách đặt tên phù hợp nhất với bản thân để clean code. Nếu có sai xót hoặc thắc mắc gì, các bạn có thể để lại bình luận bên dưới bài viết để giúp mình phát triển bài viết tốt hơn. Cảm ơn các bạn đã theo dõi bài viết!

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

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

Xem thêm Việc làm C++ hấp dẫn trên TopDev

3 Hiểu Lầm Về XPath Trong Web Automation

3 Hiểu Lầm Về XPath Trong Web Automation

Bài viết được sự cho phép của vntesters.com

Nhận diện web elements (element identification) là bước không thể thiếu khi automate web testing. XPath (được W3C khuyên dùng) chính là giải pháp tối ưu cho vấn đề này. Đa số các web automation tools đều hỗ trợ XPath, kể cả Selenium WebDriver. Dù vậy, sử dụng XPath hiệu quả thành thục không dễ, đòi hỏi nhiều thời gian tìm hiểu và “khổ luyện”.

Bài viết sẽ giúp bạn vén bức màn bí ẩn về 3 lỗi lầm thường gặp khi sử dụng XPath và cách khắc phục chúng. Hy vọng bạn có thể tận dụng được tối đa sức mạnh của “vũ khí bí mật” này.

  10 Java Web Framework tốt nhất
  Biện hộ: Vì sao các Developer không test phần mềm của họ?

[1] XPath là property của web element

Hiểu XPath bằng phép so sánh này là xu hướng tự nhiên khi bạn mới học về XPath. Nhưng dần dần bạn sẽ thấy cách hiểu tương tự đó khá nguy hiểm. Giả dụ bạn copy XPath của 1 button (<input>) trên Chrome bằng cách right click lên web element và chọn Copy > Copy XPath:

3 Hiểu Lầm Về XPath Trong Web Automation

Bạn sẽ nhận được chuỗi sau:

//*[@id=”Login”]

Trong khi đó, nếu bạn dùng Firebug (1 add-on của Firefox) trên cùng button, bạn sẽ nhận được kết quả hoàn toàn khác biệt:

/html/body/div/table/tbody/tr[5]/td/input

Tại sao XPath “property” của cùng 1 web element lại không hề giống nhau chút nào, dù web element này không thay đổi?

Bởi vì XPath thực sự không phải là “property” của control. Theo định nghĩa, XPath chỉ là ngôn ngữ để miêu tả cách tìm kiếm 1 web element mà thôi. Do vậy, những tools khác nhau trả về XPath của 1 web element hoàn toàn khác nhau là chuyện “bình thường như bức tường”.

Điều này ngầm định rằng bạn phải là người quyết định XPath nào dễ đọc (readable) và ổn định (reliable) nhất để locate 1 web element.

Một số test automation tools như TestArchitect (sản phẩm của LogiGear) cung cấp sẵn chức năng construct XPath “đẹp”. Screenshot bên dưới minh họa XPath mà TestArchitect gợi ý cho bạn (cùng chỉ đến button trong 2 ví dụ phía trên).

3 Hiểu Lầm Về XPath Trong Web Automation

Đường dẫn này (//input[@id=’Login’]) “đẹp” hơn bởi vì:

  • Chi tiết hơn gợi ý từ Chrome (//*[@id=”Login”]). Đường dẫn của Chrome sẽ chấp nhận tất cả elements có ID = “Login” dù element đó thuộc loại gì. Giả sử trang web có 1 element <td> cùng ID = “Login”, đường dẫn Chrome có thể trả về kết quả sai.
  • Ít “dễ vỡ” hơn gợi ý từ Firebug (/html/body/div/table/tbody/tr[5]/td/input). Giả sử <input> tag này được developer đổi sang <tr> thứ 8, đường dẫn Firebug sẽ trả về rỗng (null).

Dù XPath nào có “đẹp” đến đâu đi nữa, bạn vẫn phải là người quyết định cuối cùng.

[2] XPath không ổn định

Ấn tượng này cũng dễ hiểu vì đôi lúc test run của bạn fail trên Firefox vì ban đầu bạn capture trên Chrome và ngược lại. Cẩn thận điều tra một chút bạn sẽ thấy có sự khác biệt.

Trên Chrome:

//input[@id=’stdinput-00001′]

Trên Firefox:

//input[@id=’stdinput-0000A’]

Đây có thể là kết quả của việc developer generate elements động, một kỹ thuật khá phổ biến khi phát triển web apps. Có thể trong lúc code, anh chàng developer nào đó đã gắn liền việc tạo web elements vào loại browser. Đây là việc làm đi ngược với tiêu chí tăng testability. Dù vậy, đôi lúc lỗi lầm vẫn xảy ra.

Nếu bạn không để ý kỹ, bạn có thể đổ lỗi cho XPath. Nhưng thực tế kẻ tội đồ không phải XPath mà là cách generate ID cho controls đặc dị trên. Trong lúc chờ đợi developer fix sự bất đồng bộ này để tăng testability, bạn có thể tiếp tục công việc testing bằng 1 thủ thuật nho nhỏ như sau:

//input[contains(@id, ‘stdinput-00001‘) or contains(@id, ‘stdinput-0000A‘)]

Chúc mừng! Tests của bạn đã có thể chạy thành công trên cả 2 browsers.

[3] XPath là “silver bullet”

Trong tiếng Anh, cụm từ “silver bullet” miêu tả 1 giải pháp one size fits all (một câu trả lời cho mọi vấn đề). Phụ thuộc vào XPath quá mức mà không cẩn thận phân tích và thấu hiểu web apps bạn đang test sẽ làm bạn hết sức ngỡ ngàng khi nhận được kết quả failed bất ngờ. Cần hiểu rằng cùng 1 XPath có thể trả về nhiều elements khác nhau tùy vào tình huống. Ví dụ:

//a[.=’Mac’]

Khi bạn dùng XPath trên, bạn muốn lấy <a> element này:

3 Hiểu Lầm Về XPath Trong Web Automation

Nhưng bất ngờ thay, trong thực tế bạn nhận được element này:

3 Hiểu Lầm Về XPath Trong Web Automation

Do vậy, để chắc chắn luôn lấy đúng element, bạn nên đầu tư thời gian mổ xẻ và hiểu rõ về cấu trúc trang web mình đang test. Trong ví dụ trên, bạn có thể dễ dàng phân biệt 2 web elements bằng ancestor của chúng .

XPath của search result (case #1):

//div[@id=’content’]//a[.=’Mac’]

XPath của breadcrumb button (case #2):

//div/ul/li/a[.=’Mac’]

Kết luận

Hy vọng rằng làm sáng tỏ 3 hiểu lầm này có thể giúp bạn hiểu XPath, nhận diện element khi viết test case dễ dàng và test suite của bạn sẽ chạy ổn định hơn.

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

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

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Phân chia dữ liệu – Sharding/Data Partitioning

Phân chia dữ liệu

Bài viết được sự cho phép của tác giả Edward Thiên Hoàng

Phân chia dữ liệu (Sharding) là một giải pháp chia nhỏ một Database lớn thành nhiều Database nhỏ, ta có thể phân tách từng bảng hoặc cả một DB ra nhiều phần nhỏ đặt ở nhiều máy chủ (server) khác nhau. Điều này sẽ giúp cho hệ thống DB của chúng ta đạt được các tính chất khả năng bảo trì (manageability), hiệu xuất (performance), tính sẵn sàng (availability), và cân bằng tải (load balancing) của ứng dụng. Và giải pháp này cũng giảm chi phí cũng như tính mở rộng (scalability) để scale up DB bằng cách dùng nhiều server nhỏ gộp lại hơn là nâng cấp một server lớn.

  26 công cụ và kỹ thuật trong Big Data có thể bạn chưa biết
  Dữ liệu lớn (Big Data) là gì? Đặc điểm và ứng dụng của Big Data

Phân chia dữ liệu - Sharding/Data Partitioning

NHỮNG CÁCH THỨC PHÂN CHIA DỮ LIỆU

Ta có 3 cách thức Sharding dữ liệu như sau:

  1. Horizontal sharding
    Là cách chia cùng dữ liệu của cùng một bảng (table) ra nhiều DB khác nhau. Ví dụ ta có bảng dữ liệu thông tin về người dùng, ta sẽ dựa trên location của người dùng để quyết định nó nằm ở DB nào, ví dụ người dùng ở Sài Gòn thì sẽ chứ ở DB_SG, thông tin người dùng ở Biên Hòa sẽ nằm ở DB_BH hay thông tin người dùng ở Vĩnh Long sẽ nằm ở DB_VL.
    Giải pháp này có một vấn đề là ta phải chọn nơi dữ liệu Sharding rất cẩn thận để không gây mất cân bằng (unbalanced) giữa các DB dẫn tới rất có thể có một vài Server sẽ thành điểm nóng (hot spot), ví dụ người dùng ở Sài Gòn chắc chắn là đông hơn rất nhiều lần người dùng ở Biên Hòa hay Vĩnh Long.
  2. Vertical sharing
    Là cách sharding dữ liệu dựa trên tính năng (feature) của hệ thống. Ví dụ ta thiết kế một hệ thống chia sẻ ảnh giống Instagram, ta sẽ lưu thông tin của User vào DB_Users, lưu thông tin ảnh họ up lên trên một DB khác là DB_Photos và thông tin danh sách những người họ follow ở một DB thứ 3 là DB_Follow.
    Cách làm này rất là rõ ràng dễ để implement và không làm ảnh hưởng lớn đến ứng dụng, nhưng khi hệ thống lớn dần lên thì dữ liệu cũng lớn dần theo, do đó ta lại phải thực hiện sharding tiếp những DB trên từng feature (bởi vì 1 DB không thể sử lý 10 tỷ bức ảnh của 140 triệu user được).
  3. Directory Based sharding
    Cách này sẽ yêu cầu ta phải thiết kế một “lookup service” có tác dụng quyết định ánh xạ (mapping) dữ liệu sẽ nằm ở đâu, DB nào. Mỗi khi có request ghi hoặc đọc sẽ thông qua lookup service để mapping vị trí sẽ đọc và ghi. Khi business mở rộng số lượng server có thể tăng lên mà không ảnh hưởng hay đòi hỏi ứng dụng phải thay đổi theo.
Phân chia dữ liệu - Sharding/Data Partitioning

NHỮNG TIÊU CHÍ ĐỂ PHÂN VÙNG DỮ LIỆU

Bên trên ta đã tìm hiểu và các method để sharding dữ liệu, giờ ta hãy tìm kiểu sâu hơn về các tiêu chí để phân vùng dữ liệu.

  1. Phân vùng theo key hoặc hash
    Hệ thống sẽ áp dụng các hàm băm (hash function) cho một hoặc nhiều các key chính trong dữ liệu (thường là ID) để xác định ra một con số của phân vùng nó đang nằm. Ví dụ: nếu hệ thống có 100 máy chủ DB và ID của bản ghi sẽ tự tăng lên mỗi lần một bản ghi mới được chèn. Trong ví dụ này, hàm băm có thể là ‘ID% 100, từ đó ta có thể xác định vị trí của dữ liệu. Cách tiếp cận này cần đảm bảo phân bổ dữ liệu thống nhất giữa các máy chủ. Nhưng cách làm này có một điểm yếu là mỗi khi ta thay đổi số lượng Server tăng hoặc giảm thì hàm băm cũng sẽ phải thay đổi theo và sẽ xuất hiện hiện tượng xáo trộn tập dữ liệu trên mỗi server, và đòi hỏi ta phải phân phối lại dữ liệu và xuất hiện độ trễ dữ liệu. Có một cách giải quyết vấn đề này là sử dụng Consistent Hashing (hàm băm nhất quán).
  2. Phân vùng theo danh sách (list)
    Cách phân vùng sẽ được quyết định gán một danh sách các giá trị ngay từ đầu, từ đó mỗi lần ghi một bản ghi mới ta sẽ tìm ra giá trị của bản ghi nằm ở phân vùng nào và ghi vào đó. Ví dụ ta sẽ quyết định nhóm tất cả các người dùng ở Ai-len, Na Uy, Thụy Điển, Phần Lan và Đan Mạch và một phân vùng có tên là Nordic (Bắc Âu).
  3. Phân vùng vòng tròn (round-robin) 
    Cách phân vùng này rất đơn giản là mỗi lần có thao tác ghi ta sẽ ghi vòng tròn quanh các phân vùng có sẵn. Cách làm này đơn giản nhưng rất khó để xác định dữ liệu nào ở đâu lấy ra khi cần.
  4. Phân vùng tổng hợp
    Là cách tổng hợp các giải pháp trên thành một giải pháp mới. Ví dụ ta có thể áp dụng phân vùng theo Key/Hash và sau đó xác định được key rồi ta sẽ áp dụng tiếp phân vùng theo danh sách để chứa key sau khi hash vào một danh sách cụ thể nào đó. Consistent Hashing có thể được coi là cách phân vùng tổng hợp.

CÁC VẤN ĐỀ KHI SHARDING DỮ LIỆU

Vì việc dữ liệu sẽ bị phân tán đi nhiều Server khác nhau do vậy sẽ phát sinh một vài vấn đề khi sharding dữ liệu như sau:

  1. Joins and De-normalization
    Bởi vì việc dữ liệu ở các bảng được phân bố và trải rộng đi nhiều DB/Server khác nhau nên việc join bảng dữ liệu là điều rất khó khăn và cũng không đem lại hiệu xuất bởi vì việc dữ liệu phải được queries từ nhiều máy chủ khác nhau. Để giải quyết vấn đề này ta có thể thiết kế dữ liệu dạng non-relationship DB hay còn gọi là NoSQL, giống như MongoDB hay Cassandra hai hệ NoSQL rất nổi tiếng và hỗ trợ Sharding vô cùng tốt. Tuy nhiên việc này ta phải chấp nhận rủi ro việc không nhất quán dữ liệu (inconsistency)
  2. Referential integrity
    Cũng vì lý do trên về việc truy vấn chéo dữ liệu giữa các DB nằm trên các máy chủ khác nhau là bất khả thi, do vậy việc ràng buộc khóa ngoại để bảo đảm sự toàn vẹn dữ liệu cũng là một điều vô cùng khó khăn. Hầu hết RDBMS không hỗ trợ các ràng buộc khóa ngoại trên các cơ sở dữ liệu phân tán trền nhiều server. Do vậy để đạt được điều này ta phải thực hiện điều này trên mã ứng dụng (code), điều này sẽ tăng tính phức tạp của ứng dụng.
  3. Rebalancing
    Trong suốt quá trình hệ thống vận hành có rất nhiều lý do ta thay đổi các chiến thuật hay cách thức Sharding dữ liệu, như business tăng trưởng yêu cầu thêm Server… Và mỗi khi như vậy ta phải tái cân bằng (rebalancing) dữ liệu trên tất cả các Server, có nghĩa là dữ liệu phải được phân phối lại trên toàn bộ server. Để làm được điều này mà không có độ trễ (downtime) là cực kỳ khó khăn. Mô hình sharding “Directory Based” có khả năng rebalancing tốt nhất nhưng lại tăng độ phức tạp của ứng dụng và tạo thêm một single point of failure (ví dụ “lookup service”).
    Tóm lại với Sharding thì mô hình sharding với key/hash với Consistent Hashing hiện tại là giải pháp tối ưu nhất cho việc Rebalancing.

Theo medium

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

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

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Tự tạo một hàm printf thay thế cho hàm printf mặc định trong thư viện stdio.h (phần 1)

Tự tạo một hàm printf thay thế cho hàm printf mặc định trong thư viện stdio.h

Bài viết được sự cho phép của tác giả Lê Xuân Quỳnh

Chào bạn! Lại là tôi Xuân Quỳnh đây. Bạn vẫn háo hức về những kiến thức cực kỳ cơ bản trong loạt bài lập trình C cơ bản này chứ? :))

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

  Sử dụng lệnh printf hiển thị câu chào ra màn hình

OK, bài trước các bạn đã làm quen với 1 lệnh cơ bản là printf, thuộc thư viện stdio.h. Rất hay dùng để in ra màn hình các đoạn text, các con số và nhiều thứ khác nữa. Tôi đã hứa là làm 1 hàm printf tương tự, nhưng nó thuần Việt 😀 Aha, tôi việt hóa hàm này cho bạn biết nha. Nhắc lại chương trình cũ của chúng ta như sau:

#include < stdio.h >
void main()
{
   printf(“Chao em C xinh dep”);
}

OK, bây giờ chúng ta sẽ thay thế hàm printf ở trên bằng hàm, tôi đặt tên nó là inramanhinh(“In cái gì đó trong này”) :))

Bây giờ tôi giới thiệu khái niệm mới là thủ tục. Nếu bạn nào hồi cấp 3 mà cày Pascal thì biết thủ tục là như nào rồi. Tôi nhắc lại theo cách bình dân như sau:

Thủ tục là việc nhóm các câu lệnh lại để xử lý 1 việc nào đó theo mong muốn của lập trình viên. Ở đây là tôi nhóm việc in ra màn hình thành 1 thủ tục có tên như trên. Rồi, từ khóa cho việc dịnh nghĩa là void <Tên thủ tục>. Ở đây là:

void inramanhinh(char* caicaninra)

Bạn choáng ngợp chưa? Đừng sợ, tôi sẽ chỉ cho bạn hết sợ nha. Ở trên tôi có từ khóa void. void là gì vậy trời? Ồ đó là 1 từ khóa của C, quy định cho việc viết thủ tục. Sau đó là 1 cái tên, bạn muốn đặt như nào cũng được, nhưng nhớ cho tôi 1 số quy tắc đặt tên như sau:

  • Tên thì không có dấu cách ở giữa. Chẳng hạn:

void in ra man hinh(char* caicaninra)

là sai! chứa dấu cách là em C nó không chơi đâu dấy, em ấy cần sự liên tục, anh em mà cứ đứt đoạn là em ấy chê yếu ngay :))

  • Tên không được trùng với các từ khóa của C. Từ khóa của C thì nhiều lắm, tôi copy pase cho bạn đọc nè:
auto double int struct
break else long switch
case enum register typedef
char extern return union
continue for signed void
do if static while
default goto sizeof volatile
const float short unsigned

Đó, nhưng bạn thích đọc thì đọc, không thích thì thôi 😀 Lúc nào cần cái nào thì quay ra đọc thì học nó dễ mà đỡ nhớ nhiều nhức đầu nạ :3

Bạn đặt tên thủ tục thì tránh mấy cái từ này cho tôi là ok 😀

  • Tên không được bắt đầu bằng  ký tự đặc biệt ((, #..) mấy cái đó tránh cái nà.

Rồi còn nhiều quy tắc lắm nhưng mà bạn cũng không cần mất quá nhiều thời gian cho việc này. Bạn chỉ cần nhớ đặt tên theo cách của bạn, 1 cái tên của bạn và tên đó nên gợi nhớ cái thủ tục của bạn làm cái gì.

Nhắc lại hàm đang nghiên cứu:

void inramanhinh(char* caicaninra)

bên trong 2 cái dấu ngoặc là cái gì mà hoa bay bướm lượn vậy nhỉ? bạn kéo lên keyword và xem từ khóa char. Vậy char là gì? Tiếng anh tin học char là viết tắt của character: ký tự 😀

Là kiểu dữ liệu thôi chứ không có chi mô nà. Ngoài char ra tôi nói thêm:

int  = integer = số nguyên

float = số thực

long: số nguyên nhưng phạm vi lớn hơn int

double: số thực nhưng phạm vi lớn hơn float. Nó được định nghĩa kiểu dữ liệu có mũ.(cái này là cái gì nghiên cứu sau nha=)))

Kiể dữ liệu là việc bạn chọn lựa để sử dụng trong chương trình. Ví dụ chương trình của bạn đếm đếm cây, đếm vịt gà, (đếm được) thì dùng kiểu nguyên là int. đếm nhiều quá thì cho hẳn cái long cho nó máu. Tuy nhiên cái gì cũng có giới hạn cả, máy tính cũng đếm được bao nhiêu đó rồi nó chịu 😀 Còn giửa sử giải phương trình bậc 2 thì bạn cần dùng kiểu float hoặc double, vì phương trình bậc 2 giải cho cả số thực mà. Tôi lấy ví dụ như vậy nhằm nhắc bạn 1 điều. Tùy thuộc vào bài toán mà chọn kiểu dữ liệu, chứ không phải cứ thích int thì cho int, thích float thì cho float đâu nha 😀 Nhớ nha, kỹ năng cơ bản đó. Không đến lúc sai kết quả lại bảo C ngâu :))

Vậy còn sau char tôi thêm 1 dấu * để làm cái gì rứa? Aha, nó còn được gọi là con trỏ. Con trỏ là cái gì thế? Ồ, con trỏ là con trỏ :)) Con trỏ không phải là con trỏ chuột bạn di di trên màn hình đâu nha. Hồi mới học C tôi cứ nghĩ thế mới tài :)) Con trỏ có gì hay vậy? Tôi vinh hạnh giới thiệu cho bạn, con trỏ là đặc quyền của C/C++ mà không một ngôn ngữ nào có được đặc quyền này. Cùng lắm sau này có thằng objective-c được phát triển từ C cũng có thôi.

Vậy con trỏ thì ta nên hiểu như nào cho đúng?

Ở đây nếu tôi không dùng dấu * thì nó hiểu đó là kiểu char bình thường như cân đường hộp sữa. Bạn gặp * bạn hiểu đó là kiểu dữ liệu con trỏ. Con trỏ hơn ở biến thông thường điểm nào, tôi sẽ làm rõ như sau:

Giả sử bạn cần sử dụng biến để nhập ký tự, bạn dùng char. 1 ký tự bạn khai báo như sau:

char < tên biến >

Ví dụ:

char a;

tên biến nó cũng có quy tắc đặt tên, nhưng bạn nên đặt tên gợi nhớ với cái bạn cần. Bạn có thể đặt tên:

char conlon; char contrau; char hihi;

thoải mái, dài bao nhiêu cũng được, nhưng mấy cái tên cần nhắc nhớ cho bạn nó để làm gì. Đằng sau bạn thêm cho tôi 1 dấu ; nhằm mục đích kết thúc quá trình đặt tên biến.

Vì nó là lưu 1 ký tự cho nên bạn có thể gán giá trị cho biến này. Giả sử tôi có đoạn chương trình:

char c;
c = 'm';

Tôi khai báo 1 biến c. sau đó tôi gán biến c là ký tự m. Bạn để ký tự m trong 2 dấu nháy đơn nhé.

Bây giờ để in ra ký tự c này tôi viết:

printf("c = %c", c);

Chương trình đầy đủ:

#include < stdio.h >
void main()
{
   char c;
   c = 'm';
   printf("c = %c", c);
}

Kết quả trên màn hình:

Tự tạo một hàm printf thay thế cho hàm printf mặc định trong thư viện stdio.h (phần 1)

Đấy nó in ra c = m 😀

Bạn nào chưa biết gõ lệnh thì vui lòng xem bài 1 nha.

Bạn quay lại câu lệnh này tôi giải thích:

printf("c = %c", c);

%c là cái gì thế? %c là 1 cái nhãn, bạn hiểu nó sẽ thay thế ký tự vào đó. c = character. Nó sẽ đưa giá trị của biến c vào %c này, nên nó mới in ra như trên :)) em C em ấy quy định như vậy thì mình phải theo thôi =))

Ngoài %c ta còn có 1 số nhãn khác:

%d = để in ra số nguyên (d = double)

%f = để in ra số thực.(f = float)

Nếu bạn muốn in ra 2 số thập phân sau dấu phẩy thì thêm:

%2.2f: đằng trước bạn đặt bao nhiêu cũng được, đằng sau viết số 2 thì nó ra 2 số sau dấy phẩy. Tương tự %d cũng vậy nha :))

ví dụ: printf(“so thuc = %2.2f”, biensothuc);

%p = in ra địa chỉ con trỏ (p = pointer)

Ví dụ: printf(“dia chi cua p = %p”, pa);

=)) Bạn thấy mệt chưa? tôi khuyên bạn 1 câu như này, bạn đọc tới đâu trong bài của tôi thì bạn gõ code tới đó nhé 😀 học lập trình thì phải lập trình, như vậy mới nhớ dai được. Gõ lại mấy đoạn code đầy đủ của tôi bạn nhé.  Đọc qua thì nó nhanh quên lắm. Ok, hít 1 hơi và tiếp tục.

Tôi quay lại với vấn đề con trỏ. Vậy là với biến thông thường, bạn khai báo theo kiểu dữ liệu bạn muốn + tên biến bạn nghĩ ra. Thì lúc đó, máy tính của bạn sẽ cấp cho bạn 1 vùng nhớ để lưu. Hoàn toàn tự động. Bạn chỉ thấy được biến và giá trị của nó thôi. Thế còn bây giờ, bạn muốn xem biến đó nằm ở đâu trong máy tính của bạn? Bạn dùng cách này. Bạn them dấu & trước biến của bạn. Ví dụ &a thì nó lấy địa chỉ của bạn. Chương trình thí dụ:

#include < stdio.h >
void main()
{
    char c;
    c = 'm';
    printf("Dia chi cua c = %p", &  c);// ban viet lien dau &  nhe, thang wp ngau qua
}

Ở trên, bạn thay %c bằng %p để in ra địa chỉ. Bạn thêm dấu & trước c để lấy địa chỉ.

Kết quả như sau:

Tự tạo một hàm printf thay thế cho hàm printf mặc định trong thư viện stdio.h (phần 1)

Bạn thấy gì không? kết quả là 0028FF2F :)) Trông hoa mắt chưa. Vừa số vừa chữ cơ :v

Chữ cái F trên nghĩa là gì? Nó đang in ra hệ 16 bạn nhé. Hệ 10 bạn học từ hồi cấp 1 là các số từ 0 tới 9. Lên cấp 2, cấp 3 bạn học thêm hệ 16 với các số từ 0 tới 9 và các chữ cái: A để mô tả 10, B = 11, C= 12, D = 13, E = 14, F = 15. 😀

Ai quan tâm tới cách đổi cơ số 10 sang cơ số 16 không? Rảnh tôi sẽ hướng dẫn, tạm thời bài này bạn hiểu địa chỉ đó cũng là 1 cái số, số to quá nên dùng cơ số 16 để in cho tiện.

Vậy ví dụ trên, bạn hiểu biến c lưu giá trị m và nằm tại địa chỉ 002FF2F. Trên máy bạn địa chỉ này chắc chắn không giống tôi đâu :))

Vậy, bạn hiểu à hóa ra biến mà mình sử dụng được máy tính cấp cho 1 cái địa chỉ, 1 ô nhớ, 1 con số nằm trên vùng nhớ máy tính. Và thường thì ta mới học lập trình không quan tâm mấy tới địa chỉ này. Tuy nhiên học sâu về C lại hay chơi với các địa chỉ này, nhảy qua địa chỉ này tới địa chỉ khác. Ví dụ:

#include < stdio.h >
void main()
 {
   char c1;
   char c2;
   char* pc;
   c1 = 'm';
   c2 = 'n';
   printf("Dia chi cua c1 = %p \n", & c1); //viet lien dau & va c1 nhe
   printf("Dia chi cua c2 = %p \n", & c2);// wp ngau, wp ngau :((
   pc = & c1;
   printf("Dia chi cua pc = %p \n", pc);
   pc = & c2;
   printf("Dia chi cua pc = %p \n", pc);
}

Bạn vui lòng viết từng đoạn lệnh trên vào notepad của bạn và build theo hướng dẫn các bài trước. Nhớ là viết từng đoạn 1 cho tôi nhé :)) Bắt buộc đấy. Để các bạn nhớ dai hơn.

Ở trên tôi có thêm \n để xuống dòng in cho dễ đọc thôi nạ.

Kết quả như sau:

Tự tạo một hàm printf thay thế cho hàm printf mặc định trong thư viện stdio.h (phần 1)

Rồi bây giờ ta phân tích từng đoạn 1:

char c1;
char c2;
char* pc;

Tôi khai báo 2 biến thường và 1 biến con trỏ để lưu ký tự.

c1 = 'm'; c2 = 'n';

Tôi gán c1 cho ký tự m, c2 cho ký tự n.

printf("Dia chi cua c1 = %p \n", & c1); printf("Dia chi cua c2 = %p \n", & c2);

Tôi in địa chỉ của từng thằng ra.

pc = & c1; //viet lien nhe, do loi cua wp printf("Dia chi cua pc = %p \n", pc);

Tôi gán pc cho địa chỉ c1, rồi tôi in ra.

Tương tự tôi làm với c2. Bây giờ bạn kéo lên xem lại kết quả.

Rõ ràng bạn thấy thằng pc nó là con trỏ và nhảy qua lại giữa 2 địa chỉ biến thường c1 và c2. Vậy rõ ràng biến con trỏ rất chi là hiếu động, ổng nhảy tự do lung tung đi đâu cũng được. Bạn dùng câu lệnh sau để in ra giá trị của ông pc. Chương trình full thêm 2 dòng:

#include < stdio.h >
void main()
{
 char c1;
 char c2;
 char* pc;
 c1 = 'm';
 c2 = 'n';
 printf("Dia chi cua c1 = %p \n", &  c1);
 printf("Dia chi cua c2 = %p \n", &  c2);
 pc = & c1; //viet lien dau & va c1 nhe
 printf("Dia chi cua pc = %p \n", pc);
 printf("Gia tri cua pc = %c \n", *pc);
 pc = & c2;
 printf("Dia chi cua pc = %p \n", pc);
 printf("Gia tri cua pc = %c \n", *pc);
}

Kết quả như sau:

Tự tạo một hàm printf thay thế cho hàm printf mặc định trong thư viện stdio.h (phần 1)

Bạn xem kết quả và ngẫm xem nào. Ngẫm nào ngẫm nào…

Bạn thấy đó, bạn tưởng tượng các giá trị c1 c2 là 2 vùng nhớ khác nhau trong máy tính. Còn cái ông pc là 1 ông thích trỏ tới đâu cũng được. Ông trỏ vào đâu thì coi như ông có luôn biến thường đó, ổng muốn hấp diêm hay làm gì biến đó cũng được =))

Bạn đã thấy con trỏ mạnh mẽ chưa? Chưa đâu. Càng sau bạn mới thấy được cơ.

Tôi viết cũng hơi mệt rồi. Thôi ta kết thúc bài học luôn.

Quay lại với chương trình đầu tiên, như cái tiêu đề. Ta sẽ tiếp phần 2 vào bài sau nha các tình yêu 😀

Note: Bạn chú ý dòng này cho tôi:

#include < stdio.h >

Tôi phải đặt dấu < và > ra xa vì thằng wp nó tự động mã hóa. Bạn viết code thì viết sát vào cho tôi nhé. Thứ 2 là cái dấu & và các biến đằng sau cũng viết liền nha.

Chú ý cả code style, tôi chưa biết cách chỉnh trên wp. chả lẽ tôi chụp hình code nhỉ :3
Happy

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

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

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Software Architect (SA)

Software Architect

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

Là dân IT hẳn mọi người không còn xa lạ với cụm từ Software Architect (SA) – ở đây mình tạm dịch là kiến trúc sư phần mềm. Tuy nhiên không phải ai cũng hiểu được vai trò, trách nhiệm, công việc thực sự và con đường sự nghiệp của một SA. Đây là những câu hỏi mà mình đã từng đặt ra khi bước vào những nấc thang đầu tiên của vị trí này. Mình tự đi tìm lời giải đáp cho bản thân.

  10 Công cụ Go-To Tech dành riêng cho các Software Developer
  Các nền tảng tuyển dụng tốt nhất dành cho Software Engineer l Cập nhật năm 2022
Software Architect (SA)

Phân loại kiến trúc sư phần mềm

Thật ra có nhiều cách để phân loại kiến trúc sư phần mềm. Tuy nhiên, ở đây mình sử dụng cách phân loại của Microsoft. Đây cũng là một cách thức phân chia khá phổ biến trong ngành phần mềm hiện nay.

Tên Mô tả
Kiến trúc sư nghiệp vụ (enterprise architect) Là cầu nối giữa chủ sở hữu sản phẩm và đội ngũ kĩ thuật. Họ là những người có kinh nghiệm chiều sâu trong lĩnh vực mà sản phẩm đang xây dựng. Chịu trách nhiệm trong việc xây dựng và phát triển yêu cầu – thiết lập viễn cảnh, bộ khung của môi trường IT trong sản phẩm.
Kiến trúc sư hạ tầng (infrastructure architect) Là người chịu trách nhiệm trong việc thiết lập, xây dựng giải pháp về cơ sở hạ tầng IT (ví dụ: mạng, các vấn đề bảo mật, thiết bị/ phương thức lưu trữ, ..) trong sản phẩm để đáp ứng nhu cầu của doanh nghiệp.
Kiến trúc sư giải pháp (solution architect) Là người chịu trách nhiệm trong việc thiết kế, xây dựng giải pháp cho những yêu cầu của sản phẩm.
Kiến trúc sư kĩ thuật (Technology-specific architect) Là người chịu trách nhiệm về một hoặc một số lĩnh vực kĩ thuật cụ thể.

Trong một số công ty hiện tại ở Việt Nam, có một vị trí gọi là Technical Architect (kiến trúc sư kĩ thuật) trong tổ chức. Vị trí này chịu trách nhiệm cho việc phân tích, đánh giá giải pháp, xây dựng kiến trúc hệ thống. Nếu ánh xạ với cách phân loại trên thì TA chính là Solution Architect.

Xem ngay việc làm Solution Architect mới nhất trên TopDev

Những tính cách cần thiết của một kiến trúc sư phần mềm giỏi

Cho dù bạn có là kiến trúc sư phần mềm nào, thì dưới đây là những tính cách bắt buộc phải có để đạt được đỉnh cao của nghề này:

  1. Nhạy bén về kinh tế: mọi kiến trúc sư khi đưa ra giải pháp cho bất cứ bài toán nào cũng đều phải cân nhắc chi phí, lợi ích tương quan của doanh nghiệp. Đây là yếu tố then chốt đánh giá hiệu quả của một giải pháp.
  2. Có tầm nhìn xa: khi tham gia vào một dự án, kiến trúc sư phải cân nhắc những giải pháp, công nghệ sắp xuất hiện, xem xét những thay đổi gần đây trong lĩnh vực công nghiệp đang phát triển… và làm cách nào để tận dụng tối đa giải pháp hiện tại trong tương lai.
  3. Nghiên cứu kĩ thuật mới: một kiến trúc sư phải luôn luôn nghiên cứu những hướng kĩ thuật mới, từ kiến trúc IT cho đến những ứng dụng và xu hướng phát triển ứng dụng.
  4. Hiểu và có khả năng ứng dụng những framework, kiến trúc hệ thống, phương pháp luận trong quá trình phát triển phần mềm
  5. Có thể làm việc trên những thông tin còn chưa rõ ràng.
  6. Khả năng truyền đạt và giao tiếp.

Làm sao để tôi có thể trở thành một kiến trúc sư phần mềm?

Kiến trúc sư phần mềm là đỉnh cao của thang nghề nghiệp khi bạn chọn đi theo con đường kĩ thuật. Để trở thành một kiến trúc sư phần mềm, bạn nên theo những bước sau:

  1. Định hướng rõ ràng về loại kiến trúc sư phần mềm bạn muốn trở thành.
  2. Xác định và xây dựng những kĩ năng cần thiết. Liên tục bổ sung kiến thức phù hợp cho loại hình kiến trúc sư mà bạn chọn.
  3. Không ngừng phấn đấu và khẳng định vai trò của một kiến trúc sư trong chính những dự án mà bạn đang tham gia.
  4. Cố gắng rèn luyện và lấy những chứng chỉ quốc tế về kiến trúc sư kĩ thuật của những tập đoàn công nghệ lớn (Microsoft hoặc Sun). Microsoft bạn cần lấy được MCA (Microsoft Certificate Architect). Đối với Sun, bạn cần lấy được chứng chỉ: SCEA (Sun Certificate Enterprise Architect).

Con đường để trở thành một kiến trúc sư phần mềm đỉnh cao và chuyên nghiệp vẫn còn ở rất xa. Và có một điều mình luôn tâm niệm là: dù ở bất kì ngành nghề nào, vị trí nào – việc phấn đấu để đạt được đỉnh cao trong sự nghiệp cũng đều đem lại những lợi ích như nhau so với những vị trí hoặc ngành nghề khác.

Kiến trúc sư phần mềm (KTSPM) cần những gì?

KTSPM, trước hết, phải thấy xa hơn những gì mà một kĩ sư bình thường thấy và thực sự hiểu rõ về hệ thống. Có một chuyện khá là kì cục là các dự án hay bắt đầu bằng cách cho KTSPM viết ngày viết đêm ra một cái gọi là framework (framework ở đâu ra mà lắm thế), sau đó lui ra, và các kĩ sư bình thường sẽ nhào vô viết thêm tính năng, và chúng ta có một phần mềm. Sau đó có thể có chút trục trặc, chậm chạp thì các KSTPM này lại quay trở lại để dọn rác.

Nhưng hãy để tôi kể câu chuyện về dự án mà tôi đang làm đã. Đầu tiên chúng tôi có một KTSPM. Người này chuẩn bị mọi thứ, từ hệ thống build, database, Spring, Hibernate này kia, và cũng viết một ít làm mẫu. Và vì chỉ là làm giúp nên rời dự án nhanh chóng. Sau đó chúng tôi bỏ một thời gian dài loay hoay vừa muốn giữ cái nền này vừa muốn đập bỏ.

Khi yêu cầu phần mềm thay đổi và vấn đề nảy sinh thì cái nền rõ ràng là không phù hợp. Nhưng cái nền là do Kiến Trúc Sư (KTS) viết ra mà. Sự thiếu dứt khoát khiến cho mọi thứ trong hệ thống mà chúng tôi xây dựng vẫn còn khá là vá víu và không linh hoạt.

Trong giai đoạn này có hai người nữa, một người là KTS và một người gần được KTS. Nhưng họ cũng chỉ viết mã cho một vài phần. Có thể là những phần khó hơn, nhưng nó chỉ là một phần nhỏ của toàn bộ bức tranh. Và nó cũng chứa những sai lầm tiềm ẩn như những nhiều phần khác. Và nó cũng có thể được hoàn thành bởi những kĩ sư khác trong dự án, mặc dù có thể là phải có một chút hướng dẫn.

Nói tóm lại, những KTSPM đang làm những việc mà kĩ sư làm, chỉ là (có thể) ở một trình độ tốt hơn.

Vậy những sai lầm mà dự án tôi gặp phải và mắc kẹt là gì?

Có thể kể ra những thứ khá cơ bản, như bỏ qua các bước an ninh cơ bản (chống XSS, CSRF), không xây dựng một dạng protocol (hay interface) thống nhất cho các request, bỏ lơ vấn đề cache và performance (cache phía server, cache phía client), không có hệ thống build tự động, không có phương pháp chung để xử lí vấn đề cross-browser, ect.

Đây là những vấn đề có tác động quan trọng tới thiết kế của phần mềm, nên không thể giải quyết một sớm một chiều được. Dĩ nhiên, phần mềm là một hệ thống phức tạp mà khi đã đầy đủ các bộ phận thì việc thay đổi sẽ tốn kém. Vì vậy, không thể ngày hôm nay nghĩ về vấn đề này thì xây dựng nó một kiểu, rồi mai gặp hay chợt nghĩ về vấn đề khác thì sửa đối nó theo kiểu khác.

Tất nhiên KTS vẫn nên là người viết những thành phần quan trọng, để góp phần tạo ra một phần mềm có chất lượng tốt. Nhưng kĩ sư giỏi thì cũng có thể viết được những phần khó, họ cũng có thể đọc sách, tìm hiểu, suy nghĩ.

Vậy thì giá trị đặc biệt của KTSPM nằm ở chỗ nào? Tại sao họ đứng trên một cấp và lương cao hơn?

Theo tôi nghĩ đấy là vì kĩ sư giỏi là những người chỉ giải quyết được những vấn đề cục bộ, riêng rẽ, chứ không thể quan sát hệ thống một cách tổng thể.

KTSPM phải là người định hướng. Họ phải liệt kê ra được những yêu cầu, vấn đề, hoặc thử thách mà dự án sẽ đối mặt, trước mắt và tương lai. Họ phải xây dựng được những quy tắc chung để kĩ sư có thể tuân theo nhằm hạn chế sai sót. Họ phải biết phân bổ nhân lực cho hợp lí với từng phần việc. Và họ phải nắm tình trạng phát triển hiện tại của phần mềm để nhận ra những bài toán hay cải tiến cần được thực hiện một cách thực sự đúng đắn và dứt khoát.

Không chỉ nhìn xa hơn những kĩ sư, KTSPM còn phải cố gắng nhìn xa hơn những gì ông chủ nghĩ. Không phải là về kinh doanh, mà là về chức năng của phần mềm. Họ phải biết trừu tượng hóa các yêu cầu cụ thể để có cái nhìn bao quát cho chức năng mà trong đó yêu cầu của những người phân tích nghiệp vụ chỉ là một lựa chọn, một hướng hiện thực cụ thể.

Ý định của con người luôn thay đổi rất nhanh, và yêu cầu cũng vậy, nên không có lí do gì lập trình viên đặt niềm tin là những thứ họ phải làm hiện tại sẽ giống vậy mãi mãi. Chuẩn bị tốt cho những lựa chọn chưa xảy ra sẽ giúp phần mềm linh động với những nhu cầu, đòi hỏi từ thị trường. Và điều quan trọng là thấy trước thay đổi của hệ thống là nhiệm vụ của KSTPM, không cần ai khác phải nói ra, và họ sẽ không thể đổ lỗi đi đâu đó như người phân tích nghiệp vụ, hay người dùng nếu không thực hiện tốt nhiệm vụ này.

Chẳng hạn, hãy nói việc hỗ trợ bookmark cho những web application dùng AJAX nhiều. Nếu một trang web mà trạng thái của nó, như đang mở tab nào, đang hiện nội dung gì, không được thể hiện trên địa chỉ thì người dùng sẽ không thể bookmark để quay lại trạng thái đó một cách nhanh chóng được.

Tuy nhiên, yêu cầu phần mềm thường quên mất chuyện này, trong khi nếu không được thiết kế ngay từ đầu thì việc chỉnh sửa thiết kế của ứng dụng để hỗ trợ chức năng này sẽ khá rắc rối. Do nên KTSPM phải biết tự thấy trước và đáp ứng chức năng ngay khi chưa có yêu cầu.

Có thể tóm lại là KSTPM trước hết phải biết nhìn xa, nhìn trừu tượng, không chỉ xây nên framework mà còn những tiêu chuẩn, quy định, và đường lối cho dự án.

Có một câu hỏi khá thú vị như thế này: What technical details should a programmer of a web application consider before making the site public?

Nếu là bạn, bạn sẽ trả lời như thế nào?

Tham khảo:

https://fly2universe.wordpress.com/2011/11/03/ki%E1%BA%BFn-truc-s%C6%B0-ph%E1%BA%A7n-m%E1%BB%81m-anh-la-ai/

https://cnttqn.com/threads/kinh-nghiem-kien-truc-su-phan-mem-can-nhung-gi.3760.html

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

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

Lộ trình để một ứng dụng thành công

Lộ trình để một ứng dụng thành công

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

Một ứng dụng thành công cần phải có những yếu tố như tính thực tiễn, đáng tin cậy, thiết kế bắt mắt, đáp ứng nhu cầu người dùng….

Trước xu thế hiện nay, số người dùng điện thoại ngày càng tăng dẫn đến nhu cầu ứng dụng di động lên cao. Tuy nhiên, trước tài nguyên phần mềm phong phú để một ứng dụng lọt vào “mắt xanh” của người tiêu dùng không phải là điều dễ dàng.

  'Toát mồ hôi' phỏng vấn tuyển dụng vào Apple
  3 tools giúp bạn tăng hiệu năng của React App một cách bất ngờ

Những hình ảnh đồ họa dưới đây hướng dẫn một cách trực quan nhất cho quá trình này, hi vọng nó có thể giúp bạn điều gì đó trong con đường phát triển ứng dụng cho chính mình.

Lộ trình phát triển một ứng dụng Lộ trình phát triển một ứng dụng

Tóm tắt lộ trình phát triển một ứng dụng thành công:

1: Bạn có một ý tưởng ứng dụng?

Nếu thế, bạn cần phải xem ý tưởng đó có những gì được gọi là “HOT”, xu thế của google trong thời điểm hiện tại hoặc sắp tới. Bạn hãy tìm những từ khóa cho ứng dụng của bạn trên google, xem xếp hạng tìm kiếm của những từ khóa cho ứng dụng đó. Nếu idea đó thực sự “HOT” thì hãy tiếp tục thực hiện ứng dụng của bạn.

2: Bạn đã tiến hành nghiên cứu chiến dich marketing cho tên ứng dụng của bạn?

Có nhiều lý do tại sao điều này lại quan trọng bạn nên tìm hiểu qua về  chiến dich marketing cho tên ứng dụng. Nếu bạn chưa có một cái tên nào tốt hãy đi đến google adwords.

3: Bạn đã lấy ảnh chụp màn hình chất lượng và có một icon cho ứng dụng thực sự tốt?

Ấn tượng đầu tiên của người dùng khi tìm đến với ứng dụng của bạn là người dùng nhìn thấy tiềm năng của ứng dụng thông qua những hình ảnh minh họa, icon ứng dụng có bắt mắt, có những thứ người dùng mong chờ ở trong ứng dụng hay không để quyết định tải về.

4: Bạn đã gửi ứng dụng của bạn để xem xét?

Bạn có thể nghĩ rằng ứng dụng của bạn là hoàn hảo, nhưng một số người ngoài cuộc có thể cung cấp cho bạn một ý kiến để giúp bạn cải thiện chất lượng của ứng dụng của bạn. Bạn có thể tìm thấy nhiều trang web review ứng dụng, cộng đồng web đó sẽ được sẵn sàng để đánh giá ứng dụng của bạn.

5: Các bạn đã test ứng dụng của bạn với ba cái tên và mô tả cho ứng dụng khác nhau?

Vâng, Để đảm bảo rằng đối tượng của bạn hoàn toàn hiểu những gì ứng dụng của bạn, bạn có thể cần để chơi xung quanh với tên và mô tả ứng dụng của bạn một vài lần để kiểm tra nó hoạt động có giống như vậy không.

6: Theo dõi bảng review ứng dụng?

Tại thời điểm này, trong khi ứng dụng của bạn vẫn đang trên con đường thành công, tôi cho rằng không nên có quảng cáo trong ứng dụng. Để có được người dùng thích ứng dụng của bạn với đầy đủ tiềm năng của nó trước khi bạn kích hoạt quảng cáo. Ở giai đoạn này, bạn cần phải bắt đầu nhận được thông tin phản hồi của khách hàng thực sự. Những review không tốt từ khách hàng cần được bạn quan tâm hơn, đồng thời có những sự hồi đáp thông qua các phiên bản tiếp theo của ứng dụng.

7: Đẩy mạnh việc tải ứng dụng.

Có nhiều cách giúp bạn đẩy nhanh việc tải ứng dụng, thông qua việc chia sẻ ứng dụng lên các diễn đàn, báo chí hoặc bạn có thể sử dụng dịnh vụ quảng cáo ứng dụng từ các nhà quảng cáo như adwords, facebook, …Nhằm đẩy nhanh việc tải ứng dụng của bạn trong thời gian ngắn.

8: Bạn đã cập nhật ứng dụng của bạn hàng tháng không?

Trong GooglePlay, Apple store hoặc bất kỳ cửa hàng ứng dụng khác, điều quan trọng là bạn nên cập nhật ứng dụng của bạn khoảng một tháng một lần. Người sử dụng được thông báo về bản cập nhật này thông qua các cửa hàng ứng dụng và điều này khuyến khích người sử dụng để quay lại ứng dụng. Việc này cho thấy ứng dụng của bạn vẫn luôn được phát triển và ngày càng hoàn thiện hơn.

9: Bạn đã có gửi thông báo cho người dùng ( push notifications )?

Mỗi khi ứng dụng bạn có thông tin, tính năng gì mới bạn có thể thông báo cho người dùng biết thông qua push notifications, hoặc người dùng sau một thời gian dài không sử dụng ứng dụng bạn có thể gửi thông báo cho người dùng nhắc nhở quay lại sử dụng ứng dụng thường xuyên hơn.

10: Bây giờ xây dựng mạng ứng dụng của bạn.

Xây dựng mạng lưới ứng dụng của bạn cho phép bạn thúc đẩy các ứng dụng của bạn và xây dựng một lương khách hàng quen thuộc cho ứng dụng của bạn. Nó cũng cho khách hàng của bạn thấy rằng bạn là một nhà sản xuất ứng dụng thành công, tin cậy.

Tham khảo từ: developer-tech.com

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

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

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Rethinking the hjkl

Rethinking the hjkl

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

Chắc cũng có đôi lần mình nhắc tới vấn đề này trên blog, đại khái là từ khi xài vim, mình mắc phải một vấn đề khó chữa, đó là, có những lúc mình rơi vô trạng thái không muốn làm gì mà chỉ ngồi bấm hjkl để chạy đi chạy về trên file, từng dòng một, từng kí tự một…

Thực ra khi mình có làm việc thì cũng vậy, việc di chuyển từng dòng và từng kí tự một khiến cho tốc độ làm việc của mình giảm đi khá nhiều. Nên gần đây mình có thay đổi một tí trong cách mình xài vim.

  Cảm ơn Vim, mình đã dừng code bằng VS Code.
  Cách mạng 0.4 của Neovim: Floating Window

Đầu tiên, để di chuyển nhanh hơn, hiển nhiên là mình sẽ sử dụng motion. Ví dụ nhảy tới trước 10 dòng (10j) hay nhảy lui 5 dòng (5k), hay nhảy tới một dòng thứ n bất kỳ (:n).

Tiếp theo, là nhảy nhanh đến một kí tự trong một dòng bằng f hoặc F, ví dụ, bấm f kèm theo một kí tự để nhảy đến vị trí tiếp theo có kí tự đó trên dòng hiện tại. Bấm ; để lặp lại thao tác nhảy đó với kí tự tiếp theo.

Lệnh F nhảy hướng ngược lại với lệnh f.

Giờ mới tới phần thú vị. Đó là remap lại phím h và l thành b và w (để dịch chuyển theo word thay vì character). Làm như vậy sẽ giúp di chuyển nhanh hơn, và khi cần di chuyển chậm lại thì mình map tổ hợp Shift + L / Shift + H về dạng dịch chuyển từng character.

nnoremap L l
nnoremap H h
nnoremap l w
nnoremap h b

Mặc định, vim có tổ hợp Ctrl + D và Ctrl + U để nhảy lên xuống từng trang màn hình, nhưng bố trí phím như vậy hơi phiền phức đối với mình nên mình cũng remap lại thành Ctrl + K và Ctrl + J:

nnoremap <C-k> <C-u>
nnoremap <C-j> <C-d>

Thêm nữa, vì có một thời gian xài Emacs nên mình cảm thấy tổ hợp phím Ctrl + F / Ctrl + B để dịch chuyển trái phải trên một dòng rất tiện dụng, nhất là khi đang ở trong INSERT mode, kèm theo đó là tổ hợp phím Ctrl + A / Ctrl + E để nhảy tới đầu / cuối của một dòng, cũng trong INSERT mode, cho nên đem cái này vô trong vim luôn:

inoremap <C-f> <Right>
inoremap <C-b> <Left>
inoremap <C-e> <C-o>$
inoremap <C-a> <C-o>^

Vậy mới thấy cái lợi của việc xài nhiều editor khác nhau  đi nhiều học nhiều, ăn cắp nhiều thứ về mix lại với nhau rồi xài.

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

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

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Vùng lùng bùng

Vùng lùng bùng

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

Người ta nói nhiều về cái gọi là vùng an toàn, đại khái nó là một trạng thái về mặt tinh thần, mà khi đặt mình trong trạng thái đó, bạn cảm thấy vui vẻ, thoải mái, không áp lực, làm việc gì cũng thấy thuận lợi và thắng lợi, lý do? tại vì ở trong đó bạn chỉ cần sử dụng 30% khả năng, trí tuệ, tinh thần và thể lực của bản thân.

  "Dân làm Product khác hoàn toàn 180 độ với dân làm outsourcing"
  Bí kíp để host apps hoàn toàn miễn phí

Tác hại của vùng an toàn là bạn chẳng đi tới đâu cả, không tiến, không tới, không học thêm được gì, cũng chẳng thể nào giàu có hơn cả về kiến thức, kinh nghiệm lẫn tài chính.

Người ta cũng nói, bước ra khỏi vùng an toàn, bạn sẽ đến vùng nguy hiểm, nơi mà bạn sẽ được trải nghiệm, hay nếm trải, học hỏi nhiều hơn, cố gắng nhiều hơn và gặt hái cũng nhiều hơn.

Nhưng mà thực ra chuyện đó không hoàn toàn đúng.

Ngay khi bước ra khỏi vùng an toàn, nơi mà bạn đặt chân đến không phải vùng nguy hiểm mà là vùng lùng bùng. (danh từ được phát minh bởi một triết gia vô tiếng ở thế kỷ 21)

Tại đây, bạn đánh mất bản thân, không biết mình sẽ đi về đâu, trong lòng cực kì hoang mang và không biết được mình nên làm cái gì tiếp. Những thứ bạn nghĩ mình đã biết, thì bạn đã biết hết rồi. Nhưng bạn không biết là mình chưa biết cái gì, và cần biết mình chưa biết cái gì, cũng chưa biết được cái gì mình chưa biết. Tiến thoái lưỡng nan. Kết quả là bạn sẽ tìm cách quay trở lại cái vòng an toàn và ngủ yên trong đó.

Đó là lý do tại vì sao nhiều người dù có cố gắng vẫn không thể thoát ra khỏi cái vòng an toàn của bản thân.

Giải pháp ở đây là gì?

Không biết.

Có lẽ mỗi người sẽ có một cách khác nhau để vùng vẫy quẫy đạp để có thể bước tiếp ra khỏi vùng lùng bùng, hoặc có khi là chỉ đi quẫy thôi.

Nói về kinh nghiệm bản thân, thực ra mình cũng không biết là mình đã thoát ra khỏi vùng lùng bùng này chưa, mình chọn cách đi lùi, bắt đầu rà soát lại kiến thức của bản thân từ những gì cơ bản nhất, từ đó mình tìm ra vô số lỗ hổng kiến thức và bắt đầu vá víu nó một cách nghiêm túc hơn :v Ít ra phương pháp này cũng giúp mình không bị mất phương hướng khi nằm trong vùng lùng bùng này nữa.

Còn chuyện có đi tiếp đến vùng không an toàn được không thì chắc để dành sau này viết tiếp.

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

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

Xem thêm Việc làm Developer hấp dẫn trên TopDev

TypeScript vs JavaScript

TypeScript vs JavaScript

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

TypeScript là gì

TypeScript làm một ngôn ngữ lập trình mã nguồn mở được phát triển bởi Microsoft. Cha đẻ của TypeScript là Anders Hejlsberg, một kiến trúc sư trưởng (Lead Architect) của ngôn ngữ C# và là cha đẻ của ngôn ngữ lập trình Delphi và Turbo Pascal.

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

Typescript khác với JavaScript thế nào

Có thể nói TypeScript là một phiên bản nâng cao của JavaScript vì nó bổ sung những kiểu dữ liệu tĩnh và các lớp hướng đối tượng, đồng thời nó bao gồm luôn các phiên bản ES mới nhất (tùy version của TypeScript).

** ES5 = ECAMScript 5 được release năm 2009
** ES6 = ECAMScript 6 được release năm 2015
** Hiện tại là ES9 = ECAMScript 2018 là phiên bản Javascript mới nhất tính tại thời điểm mình viết bài này.

2. Các file TypeScript có đuôi (phần mở rộng – extension) là *.ts . Trong khi các file JS có đuôi được biết là *.js

3. Code được viết bằng TypeScript sẽ được biên dịch thành JavaScript thuần. Thường thì chúng ta sẽ dùng lệnh tsc để biên dịch vì trong TypeScript có tích hợp sẵn một trình biên dịch được viết bằng TypeScript luôn.

4. Với TypeScript chúng ta có thể khai báo biến với từ khóa: varlet và const. Trong khi var chỉ được dùng trong JS ( hình như từ ES6 trở đi JavaScript cũng dùng được var, let và const)

5. Các biến trong code TypeScript thường được dùng với kiểu dữ liệu rõ ràng hơn trong code JavaScript.

Ví dụ 1: Khai báo biến trong TypeScript

var name: string = "Thang Pham";
var isSingle: bool = true;

Ví dụ 2: Khai báo biến trong JavaScript

var name = "Thang Pham";
var isSingle = true;

6. TypeScript kiểm tra kiểu của các biến khi biên dịch code (compile time) trong khi JS kiểm tra lúc chạy (run time)

Ví dụ 3: TypeScript kiểm tra kiểu dữ liệu

function add(num1: number, num2: number){
    return num1 + num2;
}
add(1, 2); //3
add(1, "hai"); //error

Ví dụ 4: JavaScript kiểm kiểu dữ liệu

function add(num1: number, num2: number){
    return num1 + num2;
}
add(1, 2); //3
add(1, "hai"); //1hai

Xem thêm vị trí tuyển dụng Javascript các công ty lớn tại đây

Tại sao viết code dùng Typescript thay vì dùng Javascript

  • TypeScript được sử dụng để code Front-end như Angular 2 (và các phiên bản về sau), React, Ionic,… và back-end như NodeJs.
  • TypeScript hỗ trợ đầy đủ các tính năng mà JavaScript có với các phiên bản JavaScript mới nhất (ECMAScript versions) vì như mình đã nói nó được xem như là một bản nâng cao của JS.
  • Bạn có thể code với JS thì với qua TypeScript cũng như vậy. Vì dù sao thì code TypeScript cũng sẽ được biên dịch lại thành JS mà.
  • TypeScript giúp bạn viết code theo phong cách OOP như: C#, Java. Nghĩa là nó có: class, abstract class, interface, encapsulation, ….
  • Dễ dàng hơn để phát triển các dự án lớn vì nó giúp bạn kiến trúc hệ thống theo Module, namespace.
  • Bạn sẽ dễ dàng code TypeScript khi mà nó được tích hợp trong rất nhiều IDEs như: Visual Studio Code, Sublime Text,…

Đó là những gì mình hiểu về TypeScript. Hy vọng giúp được anh em đang tìm hiểu về TypeScript có được kiến thức nền tảng.

Hãy cho mình biết ý kiến bằng cách comment bên dưới nhé.

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

 

Xem thêm Việc làm lập trình Typescript hấp dẫn trên TopDev

Tái cấu trúc mã nguồn: Chuẩn hóa mã

Tái cấu trúc mã nguồn: Chuẩn hóa mã
Bài viết được sự cho phép của BBT Tạp chí Lập trình
Chuyển các phương thức về lớp phù hợp hơn.

Việc di chuyển phương thức giữa các lớp là công việc diễn ra thường xuyên trong tái cấu trúc. Việc di chuyển này giúp cho các lớp có kích thước phù hợp hơn, và các lớp ít phụ thuộc vào nhau mà khả năng hợp tác giữa các lớp tốt hơn.

  04 Điều Cần Chú Ý Cho Người Mới Làm Automation Test
  "Code dễ đọc" là như thế nào?

Các bước:

  1. Kiểm tra có nên di chuyển các thuộc tính mà phương thức phải dùng
  2. Kiểm tra xem có khai báo của phương thức ở lớp cha và lớp con
  3. Khai báo phương thức ở lớp đích
  4. Sao chép mã từ lớp nguồn tới lớp đích sao cho phương thức hoạt động được
  5. Biên dịch lớp đích
  6. Xác định tham chiếu phù hợp ở lớp nguồn
  7. Chuyển phương thức ở nguồn gọi tới phương thức của lớp đích
  8. Biên dịch và kiểm thử
  9. Xác định xem có xóa phương thức ở lớp gốc và gọi trực tiếp tới phương thức ở lớp địch
  10. Nếu xóa phương thức ở lớp gốc thì phải thay toàn bộ lời gọi từ phương thức này tới phương thức ở lớp mới
  11. Biên dịch và kiểm thử

Ví dụ:

  1. Ta có lớp Account (tài khoản). Nhưng khi nhiều loại tài khoản và mỗi loại tài khoản có cách tính tiền phí khác nhau, nên ta muôn chuyển hàm _overdraftCharge
    vào lớp AccountType
    [sourcecode language="java"]
    class Account...
       double overdraftCharge() {
           if (_type.isPremium()) {
               double result = 10;
               if (_daysOverdrawn &amp;gt; 7) result += (_daysOverdrawn - 7) * 0.85;
               return result;
           }
           else return _daysOverdrawn * 1.75;
       }
    
       double bankCharge() {
           double result = 4.5;
           if (_daysOverdrawn &amp;gt; 0) result += overdraftCharge();
           return result;
       }
       private AccountType _type;
       private int _daysOverdrawn;
    
    [/sourcecode]
  2. Thuộc tính _daysOverdrawn được dùng ở phương thức là một thuộc tính là của mỗi tài khoản, nên ta không di chuyển thuộc tính.
  3. Trong trường hợp này phương thức không được khai báo ở lớp cha cũng như lớp con.
  4. Khai báo phương thức ở lớp đích và sao chép mã tới lớp đích sao cho phương thức hoạt động được
    [sourcecode language="java"]
    class AccountType...
       double overdraftCharge(int daysOverdrawn) {
           if (isPremium()) {
               double result = 10;
               if (daysOverdrawn &amp;gt; 7) result += (daysOverdrawn - 7) * 0.85;
               return result;
           }
           else return daysOverdrawn * 1.75;
       }
    
    [/sourcecode]
  5. Chuyển phương thức ở nguồn gọi tới phương thức của lớp đích
    [sourcecode language="java"]
    class Account...
       double overdraftCharge() {
           return _type.overdraftCharge(_daysOverdrawn);
    }
    
    [/sourcecode]
  6. Ta xóa phương thức ở lớp gốc và gọi trực tiếp tới phương thức ở lớp đích
    [sourcecode language="java"]
    class AccountType...
       double overdraftCharge(Account account) {
           if (isPremium()) {
               double result = 10;
               if (account.getDaysOverdrawn() &amp;gt; 7)
                  result += (account.getDaysOverdrawn() - 7) * 0.85;
               return result;
           }
           else return account.getDaysOverdrawn() * 1.75;
       }
    
    [/sourcecode]
  7. Biên dịch và kiểm thử
  • Chuyển các trường về lớp phù hợp hơn.

    Nếu một trường (thuộc tính) nên được sử dụng ở một lớp khác phù hợp hơn hoặc khi ta thực hiện việc phân tách lớp thì thực hiện việc di chuyển các trường là điều cần thiết.

    Các bước:

  1. Nếu trường đó là public, ta phải bao gói nó
  2. Biên dịch và kiểm thử
  3. Tạo trường ở có getter và setter ở lớp đích
  4. Biên dịch lớp đích
  5. Xác định cách tham chiếu tới lớp đích
  6. Xóa trường ở lớp nguồn
  7. Thay thế tham chiếu tới lớp nguồn bằng lớp đích.
  8. Biên dịch và kiểm thử

Ví dụ:

Ví dụ ta có lớp Account (tài khoản) và ta muốn chuyển trường _interestRate vào lớp AccountType

[sourcecode language="java"]
Class Account...
   private AccountType _type;
   private double _interestRate;

   double interestForAmount_days (double amount, int days) {
       return _interestRate * amount * days / 365;
   }

[/sourcecode]
  1. Tạo trường ở có getter và setter ở lớp đích
    [sourcecode language="java"]
    class AccountType...
       private double _interestRate;
    
       void setInterestRate (double arg) {
           _interestRate = arg;
       }
    
       double getInterestRate () {
           return _interestRate;
       }
    
    [/sourcecode]
  2. Thay thế tham chiếu tới lớp nguồn bằng lớp đích.
    [sourcecode language="java"]
    private double _interestRate;
    
       double interestForAmount_days (double amount, int days) {
           return _type.getInterestRate() * amount * days / 365;
       }
    
    [/sourcecode]
  3. Biên dịch và kiểm thử
  • Đổi các định danh: Đổi tên phương thức, thuộc tính, lớp để không dài, đủ mô tả ý nghĩa, và phù hợp với chuẩn.

    Các bước:

  1. Kiểm tra xem phương thức có được triển khai ở lớp cha hay lớp con không. Nếu có thì phải thực hiện việc thay đổi này với từng triển khai này
  2. Tạo phương thức với tên muốn đổi và sao chép mã của phương thức nguồn vào
  3. Thay đổi các lời gọi tới phương thức cũ bẳng phương thức mới
  4. Xóa phương thức cũ.
  • Kéo lên (pull up): chuyển một thành phẩn của các lớp con lên cho lớp cha.

    Việc xóa bảo mã lặp là một việc quan trọng. Mặc dù việc mã lặp vẫn hoạt động bình thường, nhưng sẽ khó khăn cho rất nhiều việc như khó bảo trì.

    Các bước:

  1. Kiểm tra xem các phương thức ở các lớp con có nguyên mẫu giống nhau không.
  2. Nếu giống nhau thì sao phương thức từ một lớp con lên lớp cha
  3. Xóa phương thức ở từng lớp con và kiểm thử xem có lỗi gì không tới khi chỉ còn phương thức ở lớp cha.

Ví dụ:

  1. Ví dụ ta có các lớp như Hình 6 và muốn kéo phương thức chargeFor lên lớp cha

Hình 6. Các lớp trước khi thực hiện pull up

  1. Ta sẽ tạo phương thức giống hệt ở lớp con ở lớp Customer ta sẽ có như Hình 7

Hình 7. Lớp sau khi thực hiện pull up

  • Đẩy xuống (push down): Chuyển một thành phần của lớp cha xuống cho lớp con. Khi phương thức hoặc thuộc tính chỉ có ý nghĩa ở một lớp con cụ thể mà không phải tất cả. Khi đó thực hiện việc push down là cần thiết

    Các bước:

  1. Khai báo phương thức ở tất cả các lớp con và sao chép thân từ lớp cha xuống lớp con.
  2. Xóa phương thức ở lớp cha
  3. Xóa các phương thức ở lớp con mà không cần thiết
  4. Biên dịch và kiểm thử

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

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

Xem thêm Việc làm it các ngành hấp dẫn trên TopDev

Vietnam Web Summit 2020 – Dấu ấn đáng nhớ về hành trình kết nối và khai phá giá trị công nghệ

Vietnam Web Summit
Vietnam Web Summit

Sáng ngày 18/12, sự kiện Vietnam Web Summit 2020 VWS2020 LIVE đã chính thức diễn ra thành công với sứ mệnh kết nối, lan tỏa các giá trị về những kiến thức đến cộng đồng yêu công nghệ.

Với thách thức thay đổi hình thức tổ chức, sự kiện vẫn nhận được sự quan tâm lớn. Cụ thể chính là lượt stream ấn tượng từ 3 kênh chính thức: Website, fanpage và kênh Youtube của TopDev từ 8:00 – 17:30. Hình thức Event Online đã cho thấy sự nỗ lực lớn từ đội ngũ TopDev. Điều này vượt ra khỏi giới hạn của không gian tổ chức; khi mọi đối tượng quan tâm đều có thể theo dõi và trải nghiệm sự kiện thông qua LIVE.

Lời ngỏ từ Vietnam Web Summit 2020

Với thông điệp chủ đề “LEAD THE AGE OF REVOLUTION TECHNOLOGIES”, sự kiện trực tuyến đã ghi dấu ấn đặc biệt đối với người xem. Hơn 100,000+ lượt truy cập đến từ đa dạng khán giả như Developer, Digital Marketer, Product Owners, đại diện các tập đoàn & doanh nghiệp Việt,… đã cùng trải qua gần 40 nội dung chuyên sâu và diễn giả là những gương mặt tên tuổi, giàu kinh nghiệm tạo nên một Đại tiệc Công nghệ hoành tráng và quy mô lớn nhất năm 2020.

Vietnam Web Summit
Vietnam Web Summit 2020 – VWS20 LIVE.

Với sự tham gia của các tập đoàn Google, Heineken, Gojek, Lazada, Amanotes, NashTech, Cinnamon AI, Insider,… xuyên suốt các stage của sự kiện đã trình bày các chủ đề nổi bật nhất. Thông qua các số liệu thực tế, các báo cáo – phân tích về lĩnh vực Web, E-commerce, Data Science, Online Service, Marketing & Bussiness Development, sự kiện trực tuyến đã tạo ra một bức tranh công nghệ toàn cảnh với những xu hướng thị trường được cập nhật mới nhất. 

Google Assistant – Product của sự cải tiến vượt trội từ Google

Câu chuyện về Google Assistant và những khía cạnh chuyên sâu dường như chưa được khai thác nhiều trước đây. Do vậy, các topic về nội dung này chiếm được sự quan tâm lớn từ người xem.

Trong sự kiện trực tuyến Vietnam Web Summit 2020, hai đại diện Developer Advocate từ Google: Mrs. Jessica Dene Earley-Cha và Mrs. Mandy Chan đã có những chia sẻ đầy ấn tượng.

Vietnam Web Summit
Mrs. Jessica Dene Earley-Cha chia sẻ về định hướng Content Actions trong Topic: Multiple Ways To Build For Google Assistant.

Hai topic Multiple Ways To Build For Google Assistant Building Interactive Games For The Google Assistant được đánh giá là bắt kịp với nhu cầu tìm kiếm kiến thức chuyên sâu.

Vietnam Web Summit
Mrs. Mandy Chan phân tích về tỉ lệ tra cứu và phân bố thông tin từ Google Assistant.

Các cách thức vận hành; tương tác phát triển đối với sản phẩm Trợ lý ảo – Google Assistant đã được trình bày rất sâu sắc.

Đây cũng là cơ hội để các developer tại Việt Nam biết nhiều hơn về công cụ này. Đồng thời góp phần xây dựng một cộng đồng công nghệ phát triển toàn diện hơn.

Thách thức chuyển đổi số – Những câu chuyện từ thực tế đáng mong chờ

Chuyển đổi số ở mỗi ngành nghề đều có những thách thức nhất định. Đó là lý do vấn đề chuyển đổi số đã tiệm cận với sự phát triển chung của xu thế; góp mặt vào quá trình hình thành chân dung bối cảnh mới gắn liền với sự phát triển công nghệ. Vậy chuyển đổi số thế nào? Đâu là cách ứng dụng hợp lý? Những minh chứng cụ thể từ hành trình chuyển đổi từ Offline sang Online có gì thú vị? 

Nhắc đến Chuyển đổi số, người xem khó thể bỏ lỡ chủ đề Adapting digital transformation – An example of transformation from small business paper to cloud từ hai tài năng trẻ nhiệt huyết của 1C Việt Nam – Phạm Đình Đại Đức & Nguyễn Anh Quyết.

Vietnam Web Summit
Hai tài năng trẻ xuất sắc trong chung kết 1C Skills Camp Philippines 2020 chia sẻ về Topic: Adapting digital transformation.

Hai anh chàng đã có những chia sẻ về khoảng cách giữa việc lên kế hoạch; thiết lập và triển khai nhiệm vụ chi tiết trong một thị trường nhiều khó khăn thách thức. 

Điểm nhấn đặc biệt chính là Câu chuyện Toyota dưới góc nhìn chuyển đối số ngành ô tô.

Vietnam Web Summit
Mr. Oliver Wilke – Director Agency từ Sales SAIDigital chia sẻ về Chuyển đổi số trong Topic: How The Automotive Industry Is Finally Becoming Digital First.

Với chủ đề How The Automotive Industry Is Finally Becoming Digital First, Mr. Oliver Wilke – Director Agency từ Sales SAIDigital đã trình bày các lý do thực tế về ngành ô tô tham gia “con tàu số” (digital train) trễ hơn những ngành khác. Các thách thức về hành trình này dưới áp lực từ đại dịch Covid-19 cũng được đặt ra.

Ứng dụng AI – “Nhịp đập đầy tiềm năng” trong bối cảnh thời đại mới

Trí tuệ nhân tạo – AI (Artificial Intelligence) không còn là thuật ngữ xa lạ. Minh chứng lớn nhất là sự góp mặt của AI trong nhiều lĩnh vực. Thậm chí là từng quy trình hợp thức hóa của mỗi doanh nghiệp. Tính ứng dụng của AI và những vấn đề có liên quan luôn được giới chuyên môn dành sự quan tâm lớn.  

Những cách thức hiệu quả, thiết thực nhất trong việc thu thập dữ liệu chất lượng để huấn luyện và đào tạo AI đã được anh Nghiêm Xuân Bách – Vietnam Country Manager từ Cinnamon AI chia sẻ thông qua Topic: Data Harvesting Loop Trong Sự Dân Chủ Hóa Của AI.

Vietnam Web Summit
Anh Nghiêm Xuân Bách chia sẻ về chu trình vận hành và phát triển sản phẩm của Cinnamon AI.

Không chỉ đơn thuần dừng lại ở các kiến thức nền tảng về AI, topic còn mang đến xu hướng cộng tác giữa AI với con người. Đây được xem là giá trị nền tảng quan trọng của AI.

Nếu bạn là một tín đồ của AI thì Topic: Finding Real Love With AI từ Mr. Oscar Xing Luo – Co-Founder và CTO của Fika chắc chắn sẽ không làm bạn thất vọng.

Vietnam Web Summit
Mr. Oscar Xing Luo với Topic: Finding Real Love With AI.

Mr. Oscar đã chia sẻ về những kiến thức; cách thức tổ chức liên quan đến việc triển khai các thuật toán AI tốt nhất. Điều này có ý nghĩa quan trọng khi thiết lập nền tảng phát triển sản phẩm ứng dụng của doanh nghiệp.

E-Commerce  –  Tương lai phát triển xu thế mới

Lĩnh vực E-commerce là lĩnh vực chuyên sâu đang dần phát triển trong bối cảnh xu thế mới. Khi những công nghệ mới được áp dụng một cách hệ thống thì việc tạo ra sự thay đổi thần tốc là hoàn toàn có thể. 

Khác với thị trường Việt Nam, Progressive Web App (PWA) là một công nghệ nổi bật và có tiềm năng phát triển lớn. 

Vietnam Web Summit
Chị Ngô Kiều Anh chia sẻ về câu chuyện của công cụ công nghệ tiềm năng PWA.

Chị Ngô Kiều Anh – Project Manager SUTUNAM VIETNAM đã chia sẻ chi tiết về câu chuyện của PWA cũng như tương lai của PWA trong lĩnh vực E-Commerce qua Topic: Introduction PWA And Future Of PWA In E-Commerce. Đây là cơ hội tốt để giới lập trình viên Việt Nam hiểu và nắm bắt tốt hơn về các xu hướng công nghệ mới; giúp các bạn có những định hình chân thật hơn về tổng thể sự biến chuyển xu thế công nghệ toàn cầu.

Nếu hoạt động trong lĩnh vực E-Commerce, bạn không nên bỏ qua bài chia sẻ về Changing Customer Preferences For Digital First từ Mr. Carsten Ley – Founder, CX, OKR & Project Consultant của Asia PMO.

Vietnam Web Summit
Mr. Carsten Ley chia sẻ về chủ đề ” Changing Customer Preferences For Digital First”.

Mr. Carsten Ley đã mang đến những góc nhìn về một “tương lai” hậu Covid; về sự thay đổi của khách hàng trước xu thế digital first. Chuyên đề giúp người xem nắm bắt tốt những khó khăn và thách thức thực tế. Từ đó, lập kế hoạch chiến lược cho các mục tiêu tương lai của bản thân lẫn hoạt động phát triển của doanh nghiệp.

Vietnam Web Summit 2020 – Lời kết

Điểm giới hạn trong sự kiện lần này là thời gian lẫn không gian tổ chức. VWS2020 LIVE đã diễn ra thành công tốt đẹp. Đồng thời, sự kiện đã nhận được nhiều phản hồi tích cực từ giới chuyên môn. TopDev trân trọng cảm ơn các diễn giả, các chuyên hàng đầu từ các tập đoàn, các đơn vị, tổ chức doanh nghiệp đã hợp tác, hỗ trợ chia sẻ; tạo cầu nối lan tỏa kiến thức mới nhất từ mọi quy mô lĩnh vực.

Tất cả cùng hòa nhịp tạo nên một dấu ấn đáng nhớ về hành trình công nghệ. Hành trình của sự bứt phá về không gian từ VWS2020 LIVE đã khép lại với những khoảnh khắc đẹp. Đây thật sự là một dấu ấn đặc biệt. Vì nó mở ra những kỳ vọng mới về các mối quan hệ hợp tác mới; tạo ra sức bật phát triển mới cho mỗi cá nhân, mỗi doanh nghiệp đang làm việc trong lĩnh vực Công nghệ.

Cách thức đối phó Thủ tục “Mưu hèn kế bẩn” chốn công sở

công sở
công sở

Ma cũ ăn hiếp ma mới, đây có lẽ là một vấn đề không quá xa lạ. Chốn công sở ngoài những áp lực tồn tại trong công việc; còn cả là một bức tranh với nhiều sự thi phi. Nhiều ma cũ đã chơi các chiêu trò để dìm hàng, thách thức sức chịu đựng của các nhân viên mới. Vậy phải làm gì để đối phó với tình trạng này? Cùng TopDev tìm hiểu thông qua bài viết sau.

Chơi không fairplay – đâm sau lưng đồng nghiệp

Trong môi trường công sở, việc chơi thiếu công bằng diễn ra hằng ngày. Và tất nhiên, tùy theo từng mức độ hoàn mỹ của kế hoạch chơi chiêu mà bạn bị đâm nhiều hay ít. Thực tế bạn nên xem đây là chuyên bình thường. Vì bạn không thể làm hài lòng được hết tất cả mọi người.

công sở
Bạn đã từng bị đâm sau lưng tại chốn công sở hay chưa?

Nguyên nhân của vấn đề này rất đa dạng: có thể là do bạn giỏi hơn họ về chuyên môn; bạn là một sự đe dọa cho sự phát triển của họ sau này; hoặc đơn giản bạn thấy ghét;…

Xem thêm các việc làm về tuyển dụng Data Scientist 

Bất kỳ một vị trí nào từ freelancer IT cho đến Senior Developer hay các vị trí cao hơn, việc cạnh tranh là luôn tồn tại. Đó cũng là một trong những nguyên nhân tạo ra việc bạn bị đâm sau lưng.

Hãy lưu ý các biểu hiện mà họ tiếp cận bạn. Đây có thể là tín hiệu đáng ngờ. Họ cư xử bình thường để nắm được điểm yếu của bạn.

Và rồi không phải kế hoạch chơi bạn sẽ hiệu quả hơn sao? Vì thế, hãy thật nhạy bén, thông minh và có cách thức ứng phó thật hoàn hảo nhất.

Liệu bạn sẽ bị chơi “giáp lá cà”

Điều này cũng không quá khó hiểu! Vì ma cũ sẽ hợp tác với các đối tác mới để dành cho bạn một “sự mở đầu” vui vẻ. Và khi xong chuyện, họ kiểu “Ờ, thì đó chỉ là giao lưu giữa nhân viên cũ và nhân viên mới”.

Không phải bây giờ bạn mới có thể nhìn nhận được thực tế. Môi trường công sở hay chốn học đường nó cũng giống nhau. Ở đâu cũng được kiểm soát bởi hệ thống các quy luật về các điều lệ.

Tuy nhiên, không phải bạo hành học đường vẫn diễn ra hay sao? Vậy thì việc chơi xấu trong chốn công sở cũng tương tự mà thôi. Chỉ là cách thức thực hiện có thể sẽ tinh vi hơn, khéo léo hơn. 

Đừng lo lắng vì bạn hoàn toàn có thể thoát khỏi những nỗi khổ tinh thần ấy. Bằng cách áp dụng các cách thức đối phó thông minh, bạn hoàn toàn có thể vượt qua được. Và rồi những trờ chơi hội đồng, bắt nạt ấy chỉ là cỏn con. Họ còn phèn lắm, chưa đủ sức quật ngạ được bạn. Hành trình nghề nghiệp còn dài, ráng mà tận hưởng. 

Làm sao để đối phó với Thủ tục “Mưu hèn kế bẩn” chốn công sở?

Cạnh tranh doanh số, cạnh tranh về năng lực, cách thức cấp trên ưu ái,… đều là những nguyên nhân mà bạn có thể nhận biết rõ. Nắm rõ để bạn biết cách khôn khéo giải quyết, cư xử và thay đổi xu hướng tiếp cận mục tiêu phát triển của chính bản thân mình. 

Xem thêm các việc làm NTQ Solution tuyển dụng

Đâu là cách đối phó hữu hiệu?

Để đối phó với những “mưu hèn kế bẩn” này, bạn cần tỉnh táo, đề cao cảnh giác, làm việc cẩn thận; tỉ mỉ trong từng khâu và nên có kiến nghị thẳng với sếp nếu như công việc gặp vấn đề.

Một điểm bạn cần lưu tâm chính là không tự ý đưa ra quyết định có liên quan đến công việc chung. Và tất nhiên, bạn cần ý kiến của người có quyền hạn trách nhiệm cao hơn; hoặc đơn giản là người thứ ba.

công sở
Đâu các cách giúp đối phó tiểu nhân chốn công sở?

Để tránh trường hợp bị vu đổ lỗi, bạn nên có sự cẩn trọng. Cụ thể, bạn nên lưu lại trước những minh chứng cho các thành quả về hiệu suất thực hiện công việc. Ví dụ như các báo cáo với các thông số, cứ liệu cụ thể, được phân tích rõ ràng; các file ghi âm, các giấy tờ có liên quan có hiệu lực pháp lý;… Tất cả đều là những tài liệu cần bạn lưu trữ để phòng ngừa những tiểu nhân.

Đặc biệt, để lật mặt đối thủ, bạn nên tự nâng cao năng lực, hoàn thành tốt trách nhiệm và nhiệm vụ được giao. Đây sẽ là cú tát lớn cho những kẻ tiêu nhân chỉ đám đứng sau chơi xấu người khác.

Lời kết

Vì khi bạn có năng lực thật sự, thì tiếng nói và hành động của bạn trở nên có sức bật đủ “đánh bay” lũ ma cũ sân si, ghen tị với người khác.

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

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

NUnit – Kiểm thử Đơn vị trên Visual Studio

NUnit – Kiểm thử Đơn vị trên Visual Studio

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

Unit Testing (Kiểm thử Đơn vị) là một kỹ thuật quan trọng góp phần lớn trong việc nâng cao chất lượng phần mềm. XP (Extreme Programming) coi kiểm thử đơn vị như là một trong những kỹ thuật cốt lõi. Hiện nay, nền công nghiệp phần mềm sẽ khó chấp nhận một lập trình viên không biết hoặc không thành thạo Kiểm thử Đơn vị. Các ngôn ngữ lập trình phổ biến hiện nay đều có sẵn những framework (khung làm việc) giúp lập trình viên triển khai dễ dàng Kiểm thử đơn vị. Thay vì bạn phải tự viết các chương trình độc lập để kiểm thử hoặc phải chờ những chức năng này được tích hợp rồi mới tiến hành kiểm thử. Khung làm việc Kiểm thử Đơn vị sẽ trợ giúp các lập trình viên nhanh chóng tạo ra những test-case (ca kiểm thử), và chạy các test-case để đảm bảo chức năng mà họ vừa xây dựng đạt chất lượng (không có bug, đúng yêu cầu nghiệp vụ, v.v.). Không những thế việc sử dụng các khung làm việc sẽ giúp họ dễ dàng triển khai Automation Testing (kiểm thử tự động) và tham gia vào các dự án phát triển phần mềm với sự trợ giúp của CI (Continuous Integration – Tích hợp Liên tục).

  Cách cài đặt Android Studio phiên bản năm 2020
  Cách tạo dự án trong Android Studio phiên bản năm 2020

Tạp chí Lập trình đã có những bài viết giới thiệu với bạn đọc một số hướng dẫn sử dụng các khung làm việc để triển khai Kiểm thử Đơn vị:

●     Kiểm thử đơn vị trên Android

●     Kiểm thử Đơn vị trong JavaScript với QUnit

●     Kiểm thử đơn vị với PHPUnit trên Netbeans

Trong bài viết này tôi sẽ hướng dẫn các bạn cách thức cài đặt và sử dụng NUnit, một khung làm việc được đánh giá cao dành cho ngôn ngữ C#. Khung làm việc này tích hợp với Visual Studio dưới dạng một Extension (với bài viết này tôi dùng VS 2010 để trình bày, bạn có thể làm tương tự với các bản VS khác).

Trước hết bạn cần kiểm tra xem bản VS mà bạn đang sử dụng đã tích hợp sẵn NUnit chưa? Để làm việc này trên thanh trình đơn của VS bạn chọn Tools > Extension Manager, trong phần Installed Extensions bạn chọn Tools, nếu kết quả như sau:

NUnit – Kiểm thử Đơn vị trên Visual Studio

VS của bạn đã có NUnit…

Nếu chưa có Extension này bạn có thể cài đặt thêm bằng cách chọn tiếp Online Gallery > Tools rồi tìm theo từ khóa “NUnit”, VS sẽ kết nối Internet và tìm kiếm cho bạn.

NUnit – Kiểm thử Đơn vị trên Visual Studio

Bạn có thể tìm kiếm trực tiếp NUnit và tải về từ trang web: http://visualstudiogallery.msdn.microsoft.com. Bước tiếp theo bạn tiến hành tải, cài đặt Extension này và khởi động lại VS. Để chắc chắn VS đã tích hợp thành công NUnit bạn nên kiểm tra lại như tôi đã hướng dẫn ở trên.

Phần kế tiếp tôi sẽ hướng dẫn bạn cách sử dụng khung làm việc này cho một tình huống cụ thể. Giả sử bạn phải xây dựng một lớp có nhiệm vụ đọc một con số. Lớp này được thiết kế đơn giản như sau:

NUnit – Kiểm thử Đơn vị trên Visual Studio

Phương thức SayNumber() của lớp Counter có nhiệm vụ đọc một số (được truyền vào bởi tham số number) theo quy tắc đơn giản sau:

  • “Fizz” nếu number chia hết cho 3
  • “Buzz” nếu number chia hết cho 5
  • “FizzBuzz” nếu number chia hết cho cả 3 và 5
  • Đúng số number (ở dạng chuỗi) nếu không phải các trường hợp trên

Bây giờ chúng ta bắt đầu giải quyết bài toán này. Trước tiên bạn cần tạo lớp Counter trong một project trên VS.

[sourcecode language=”csharp”] using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace FizzBuzz
{
public class Counter
{
public string SayNumber(int number) {
throw new NotImplementedException();
}
}
}
[/sourcecode]

Bạn chớ vội hoàn thành code của phương thức này. Chúng ta sẽ bắt đầu bằng việc tạo cho phương thức này một test-case bằng cách như sau:

NUnit – Kiểm thử Đơn vị trên Visual Studio

VS sẽ sử dụng NUnit để tạo cho bạn một lớp có nhiệm vụ kiểm thử các phương thức của Counter, cụ thể là kiểm thử phương thức SayNumber().

NUnit – Kiểm thử Đơn vị trên Visual Studio

Bạn cần tạo một project để chứa các lớp kiểm thử này. Kết quả bạn sẽ có lớp CounterTest như sau:

[sourcecode language=”csharp”]

using FizzBuzz;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;

namespace TestFizzBuzz
{
…

[TestClass()] public class CounterTest
{

…

/// <summary>
///A test for SayNumber
///</summary>
[TestMethod()] public void SayNumberTest()
{
Counter target = new Counter(); // TODO: Initialize to an appropriate value
int number = 0; // TODO: Initialize to an appropriate value
string expected = string.Empty; // TODO: Initialize to an appropriate value
string actual;
actual = target.SayNumber(number);
Assert.AreEqual(expected, actual);
Assert.Inconclusive("Verify the correctness of this test method.");
}
}
}
[/sourcecode]

Bây giờ, bạn hãy tập trung vào phương thức SayNumberTest() của CounterTest, các vùng thông tin khác bạn sẽ dành thời gian tìm hiểu thêm sau khi đã thạo các bước căn bản.

Hiện tại NUnit đã tự động sinh ra trong phương thức này một loạt các mã lệnh để kiểm thử phương thức SayNumber(). Chúng ta sẽ điều chỉnh một chút code của phương thức này:

[sourcecode language=”csharp”]

public void SayNumber1Test()
{
Counter target = new Counter();
int number = 1;
string expected = "1";
string actual;
actual = target.SayNumber(number);
Assert.AreEqual(expected, actual);
}
[/sourcecode]

Những điều chỉnh với phương thức này:

  1. Đổi tên thành SayNumber1Test()
  2. Thay number với giá trị mới (số 1) – giá trị đầu vào
  3. Thay expected bằng chuỗi “1” – kết quả đầu ra cần đạt
  4. Bỏ dòng lệnh cuối cùng đi (Assert.Inconclusive(“Verify the correctness of this test method.”))

SayNumber1Test() sẽ thực thi một test-case đối với phương thức SayNumber(). Trường hợp đầu tiên chúng ta kiểm thử đó là cho đầu vào là số 1, và nếu phương thức thực hiện đúng thì kết quả nhận được sẽ phải là chuỗi “1”.

Bây giờ chúng ta sẽ chạy thử cái test-case này xem sao.

NUnit – Kiểm thử Đơn vị trên Visual Studio

Kết quả nhận được là Failed:

NUnit – Kiểm thử Đơn vị trên Visual Studio

Đây là dấu hiệu đáng mừng. Vì điều này cho thấy bạn đã hoàn thành hai pha đầu tiên trong TDD (Test-Driven Development – Phát triển Hướng Kiểm thử).

Giờ mới là lúc chúng ta quay lại để viết thêm một chút mã cho phương thức SayNumber(), bạn lưu ý rằng mình sẽ chỉ bổ sung một chút mã thôi, đủ để vượt qua cái test-case vừa rồi. Tôi sẽ code như sau:

[sourcecode language=”csharp”]

public string SayNumber(int number) {

return number + "";

}
[/sourcecode]

Chỉ đơn giản là một dòng lệnh return như trên. Sau đó chúng ta sẽ trở lại chạy cái test-case lúc trước. Và kết quả là…

NUnit – Kiểm thử Đơn vị trên Visual Studio

Xanh rồi (Passed) nhé! Vậy là chúng ta có thể tự tin SayNumber() sẽ đảm bảo thành công với những trường hợp số bình thường (không phải 3 trường hợp đầu tiên theo yêu cầu của bài toán). Nếu chưa tin bạn có thể thay số 1 bằng các số 2, 4, 7, v.v..

Nếu theo thói quen thông thường bạn sẽ quay lại viết tiếp những mã lệnh cần thiết cho SayNumber(), nhưng đừng vội làm thế. Tại sao lại vậy? sao không hoàn chỉnh luôn phương thức SayNumber()? Thật ra bài toán mà chúng ta đang có ở đây chỉ là công cụ để ta triển khai Kiểm thử Đơn vị với phương pháp TDD mà thôi. Bạn sẽ quen dần với cách thức này và thấy sự thú vị và lợi ích mà TDD mang lại cho những lập trình viên. Nếu không thì tại sao các nghệ nhân phần mềm (software craftsman) lại khuyên ta nên thực hành TDD?!

Trở lại với các test-case trong lớp CounterTest, lúc này tôi sẽ viết một phương thức khác (SayNumber3Test) để thử một trường hợp mới mà tôi nghĩ chắc chắn SayNumber() không thể vượt qua được. Test-case đó như sau:

[sourcecode language=”csharp”] [TestMethod()] public void SayNumber3Test()
{
Counter target = new Counter();
int number = 3;
string expected = "Fizz";
string actual;
actual = target.SayNumber(number);
Assert.AreEqual(expected, actual);
}
[/sourcecode]

Chắc bạn đã quen với mấy dòng mã này, tôi đang thử với trường hợp số 3, theo đề bài thì SayNumber() phải cho tôi kết quả là “Fizz”. Vì tôi nghĩ là SayNumber() không làm được điều này và để khẳng định tôi lại “Run Test”. Kết quả đây…

NUnit – Kiểm thử Đơn vị trên Visual Studio

Đúng như tôi mong đợi, test-case đầu tiên thành công nhưng test-case mới thì đỏ rồi, nguyên nhân thì chắc bạn đã rõ. Bây giờ chúng ta sẽ viết thêm một chút mã nữa cho SayNumber() để test-case này xanh nhé. Tôi làm thế này:

[sourcecode language=”csharp”]

public string SayNumber(int number)
{

if (number % 3 == 0)
{
return "Fizz";
}

return number + "";

}
[/sourcecode]

Chúng ta chạy lại các kiểm thử xem sao nhé.

NUnit – Kiểm thử Đơn vị trên Visual Studio

Tuyệt vời, xanh hết rồi phải không bạn. Giờ thì tôi có thể khẳng định SayNumber() thành công với mọi trường hợp số chia hết cho 3. Mình lại làm một cái test-case nữa nhỉ?!

Thôi nhé! Tôi nghĩ đến như vậy đủ để bạn biết được cách triển khai Kiểm thử Đơn vị với NUnit. Bạn không nhất thiết phải triển khai Kiểm thử Đơn vị như tôi đã làm (nó lòng vòng quá phải không?). Về căn bản, bạn có thể viết mã hoàn chỉnh cho SayNumber() sau đó chuyển sang viết toàn bộ các test-case mà theo đó có thể đảm bảo phương thức SayNumber() đảm bảo chất lượng. Bước cuối cùng là “Run Test” để kiểm tra. Nhưng nếu là tôi, tôi sẽ vẫn làm theo cách thức ở trên. Và tôi sẽ thực hiện thêm một bước rất quan trọng nữa trong TDD. Đó là Code Refactor (Tái cấu trúc mã nguồn). Tôi sẽ tiến hành tái cấu trúc SayNumber() trước khi viết thêm một test-case, mặc dù nó đang khá ít mã lệnh và đang rất đơn giản. Bạn nghĩ mình sẽ tái cấu trúc nó thế nào đây, bạn thử xem sao nhé!

Chúc bạn sử dụng thành thạo NUnit và thấy được lợi ích đem lại của TDD trong phát triển phần mềm :o)

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

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

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Chia sẻ hàm cách tính can chi theo tuổi

Chia sẻ hàm cách tính can chi theo tuổi

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

Xin chào các bạn, bài viết hôm nay mình sẻ chia sẽ đến các bạn cách tính can chi theo tuổi trong Sqlserver. Ví dụ: Năm 1988 => Mậu Thìn

Vd: 28/03/1988 => Bạn sinh vào ngày thứ hai năm Mậu thìn

Can có 10 can: GIÁP; ẤT; BÍNH ; ĐINH; MẬU ; KỈ ; CANH ; TÂN ; NHÂM; QUÝ. 

Chi có 12 chi: TÝ ; SỬU ; DẦN ; MÃO; THÌN ; TỴ ; NGỌ ;MÙI ; THÂN ; DẬU ; TUẤT; HỢI.

  Hướng dẫn giải bài toán phân bổ số lượng (thuật toán chia kẹo) trong sqlserver
  Log MySQL Query

Bảng tính can chi:

+ Bảng can:

0 1 2 3 4 5 6 7 8 9
Canh Tân Nhâm Quý Giáp  Ất Bính  Đinh Mậu Kỷ

+ Bảng chi:

Sửu Dần Mão Thìn Tỵ Ngọ Mùi  Thân Dậu Tuất Hợi
3 1 2 0 1 2 0 1 2 0 1 2 0
4 0 1 2 3 0 1 2 3 0 1 2 3

Các bạn tạo hàm fn_Nam_CanChi sql như sau:

CREATE FUNCTION [dbo].[fn_Nam_CanChi ]
(
	@Year int
)
RETURNS NVARCHAR(100)
AS
BEGIN
	DECLARE @Can NVARCHAR(50), @Chi NVARCHAR(50)
	SET @Can = CASE WHEN @Year%10 = 0 THEN N'Canh'
					WHEN @Year%10 = 1 THEN N'Tân'
					WHEN @Year%10 = 2 THEN N'Nhâm'
					WHEN @Year%10 = 3 THEN N'Quý'
					WHEN @Year%10 = 4 THEN N'Giáp'
					WHEN @Year%10 = 5 THEN N'Ất'
					WHEN @Year%10 = 6 THEN N'Bính'
					WHEN @Year%10 = 7 THEN N'Đinh'
					WHEN @Year%10 = 8 THEN N'Mậu'
					ELSE N'Kỷ' END
	SET @Chi = CASE WHEN @Year%12 = 0 THEN N'Thân'
					WHEN @Year%12 = 1 THEN N'Dậu'
					WHEN @Year%12 = 2 THEN N'Tuất'
					WHEN @Year%12 = 3 THEN N'Hợi'
					WHEN @Year%12 = 4 THEN N'Tý'
					WHEN @Year%12 = 5 THEN N'Sửu'
					WHEN @Year%12 = 6 THEN N'Dần'
					WHEN @Year%12 = 7 THEN N'Mẹo'
					WHEN @Year%12 = 8 THEN N'Thìn'
					WHEN @Year%12 = 9 THEN N'Tỵ'
					WHEN @Year%12 = 10 THEN N'Ngọ'
					ELSE  N'Mùi' end

	RETURN @Can+' '+@Chi

END
SQL

Và dưới đây là hình ảnh kết quả:

Chia sẻ hàm cách tính can chi theo tuổi

Thank for watching!

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

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

Xem thêm Việc làm Developer hấp dẫn trên TopDev

Cấu hình đồng bộ hai database mysql server MySQL Replication

Cấu hình đồng bộ hai database mysql server MySQL Replication

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

Trong bài viết này, mình sẽ tiếp tục trình bày các để đồng bộ dữ liệu giữa 2 Database Server sử dụng MySQL Server (MySQL Replication), thực hiện trên hệ điều hành CentOS 5.6
Trong mô hình này. Một Server sẽ đóng vai trò là MASTER, Server kia đóng vai trò là SLAVE.

Việc làm database hấp dẫn trên TopDev

Công việc mysql lương 1000$+++

Yêu cầu 2 Server:

  • Đã cài đặt MySQL

Cấu hình chung:

  • Server 1 có địa chỉ IP là: 192.168.1.131
  • Server 2 có địa chỉ IP là: 192.168.1.137
  • Database trên 2 Server cần đồng bộ có tên: dulieumau

1) Cấu hình MASTER (Server1):

Đánh lệnh để sửa lại nội dung file my.cnf

vi /etc/my.cnf
C#

Đầu tiên bạn cần chắc chắn rằng 2 dòng sau của file my.cnf đã được commnet hoặc được xóa bỏ

#skip-networking
#bind-address = 127.0.0.1
C#

Tiếp đó, trong thẻ [mysqld] thêm vào nội dung sau:

log-bin
binlog-do-db=dulieumau
server-id=1
C#

Trong đó binlog-do-db ta cho biết dữ liệu cần đồng bộ.

Sau đó ta khởi động lại MySQL. Gõ lệnh:

service mysqld restart​
C#

Tiếp theo, đăng nhập vào MySQL trên Server 1 bằng tài khoản root

mysqld -u root -p​
C#

Tạo một user để Server 2 đăng nhập và có thể Replicate

GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%' IDENTIFIED BY '123456'​
C#

Trong dòng lệnh trên thì Username là slave1 và mật khẩu là 123456

Để đảm bảo tính nhất quán dữ liệu giữa 2 database trên Server1 và Server2. Ta tiến hành ngưng các tác động làm thay đổi cơ sở dữ liệu.

FLUSH TABLES WITH READ LOCK;
C#

Tiếp tục, Xem file log của cơ sỡ dữ liệu “dulieumau” hiện tại để slave biết bắt đầu replicate tại thời điểm nào.

SHOW MASTER STATUS;
C#

Ví dụ ở đây ta có kết quả như hình dưới đây.

Chúng ta cần lưu lại 2 tham số của cột File và Position để cấu hình cho SLAVE.

2) Cấu hình SLAVE (Server 2):

Chú ý: Nếu như trước khi bạn thiết lập Replication này mà database cần Replicate của bạn đã có sẵn dữ liệu trên Server 1 thì bạn cần sao chép database này sang Server 2!
Bạn có thể thực hiện việc này bằng cách sao lưu và backup bằng tay từ server 1 sang server 2 hoặc có thể đánh lệnh sau trong server 2
LOAD DATA FROM MASTER;
==> Đảm bảo trước khi cấu hình đồng bộ hóa thì database ở 2 server là giống nhau!

Trên SLAVE  mở và thêm đoạn sau vào nội dung file my.cnf

server-id=2
master-host=192.168.1.131
master-user=slave1
master-password=123456
master-port=3306
master-connect-retry=60
replicate-do-db= dulieumau​
C#

Trong đó:

  • master-host= IP hoặc domain của MASTER
  • master-user= Tài khoản để SLAVE đăng nhập vào MASTER được tạo ở bước trên
  • master-password= là mật khẩu của User đó

Sau đó khởi động lại MySQL:

service mysqld restart​
C#

Đăng nhập vào MySQL bằng quyền root:

mysql -u root -p​
C#

Nếu Server 2 hiện đang là 1 SLAVE đang hoạt động thì ta tạm dừng nó lại:

SLAVE STOP;
C#

Cấu hình những thông tin cần thiết để SLAVE giao tiếp được với MASTER:

CHANGE MASTER TO
-> MASTER_HOST='192.168.1.155',
-> MASTER_USER='slave1',
-> MASTER_PASSWORD='123456',
-> MASTER_LOG_FILE='mysqld-bin.000001',
-> MASTER_LOG_POS=98;
C#

với MASTER_LOG_FILE và MASTER_LOG_POS là hai tham số có giá trị được ta lưu lại ở bước phía trên!

Khởi động lại SLAVE:

SLAVE START;
C#

Giải phóng các Tables trên MASTER (Server 1)

3) Testing:
Khi ta tiến hành thay đổi dữ liệu trên dulieumau ở Server 1 thì dulieumau trên Server 2 cũng thay đổi theo y như vậy! ==> Thành công!

* Một số lệnh để xem logs và kiểm tra hoạt động trên MASTER và SLAVE:

——– MASTER:
mysql> SHOW GRANTS FOR repl;
mysql> SHOW MASTER LOGS G
mysql> SHOW BINARY LOGS;
mysql> SHOW MASTER STATUS;
mysql> RESET MASTER —> ( CAUTON !!! )
——– SLAVE:
mysql> SHOW SLAVE STATUS;
mysql> STOP SLAVE;
mysql> START SLAVE;
mysql> RESET SLAVE;
C#

4) MySQL Replication theo 2 chiều:
Các bước cấu hình mình đã trình bày ở trên sẽ giúp đồng bộ dữ liệu mỗi khi Database trên Server 1 được thay đổi. Tuy nhiên nếu dữ liệu ở trên Server 2 thay đổi thì Server 1 không có được những thay đổi này! Đó là replication một chiều (MASTER –> SLAVE)
Để có thể replication chiều (MASTER <–> MASTER) ta tiến hành cấu hình 2 mô hình MASTER-SLAVE replication lồng vào nhau:
Bước 1: Server 1 là MASTER, server 2 là SLAVE
Bước 2: Server 1 là SLAVE, server 2 là MASTER

2 bước này cấu hình hoàn toàn tương tự như mình đã trình bày ở bên trên.

Thanks for watching!

Tham khảo upshell.wordpress.com

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

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

Redux selector và vấn đề sử dụng sao cho hiệu quả

Redux selector và vấn đề sử dụng sao cho hiệu quả

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

Selector

Selector là một hàm với input là ‘state’ của store và trả về một giá trị mong muốn

const selectEntities = state => state.entities;

function selectItemIds(state) {
    return state.items.map(item => item.id);
}

const selectSomeSpecificField = state => state.some.deeply.nested.field;

function selectItemsWhoseNamesStartWith(items, namePrefix) {
     const filteredItems = items.filter(item => item.name.startsWith(namePrefix));
     return filteredItems;
}

Về cách đặt tên, không bắt buộc, nhưng đa phần sẽ đặt với prefix select hoặc get

Tuyển react lương cao đi làm gấp

Khác nhau giữa useSelector và mapState

  • Khi một action được dispatchuseSelector sẽ thực hiện so sánh giữa kết quả trước đó và kết quả hiện tại, nếu khác, component bị force để re-render.
  • useSelector sử dụng so sánh === chứ không dùng phương pháp so sánh shallow (dịch vui là so sánh “nhẹ”)
  Làm việc với Redux trong ứng dụng lớn
  Redux là gì? Hiểu rõ cơ bản cách dùng Redux

Lý do sử dụng selector

  • Sử dụng lại, một selector có thể sử dụng ở nhiều nơi, nhiều component khác nhau
  • Tinh gọn, ví dụ chúng ta có entity user chứa lastnamefullnameemail, nhưng chúng ta chỉ muốn lấy email, một selector getUserEmail sẽ rất rõ ràng tinh gọn
  • Lý tưởng nhất, chỉ có reducer và selector mới biết được structure của redux store, như vậy một khi structure này có thay đổi, chúng ta chỉ việc cập nhập lại ở 2 chỗ này.
import { createSelector } from 'reselect'

const getVisibilityFilter = state => state.visibilityFilter
const getTodos = state => state.todos

export const getVisibleTodos = createSelector(
  [getVisibilityFilter, getTodos],
  (visibilityFilter, todos) => {
    switch (visibilityFilter) {
      case 'SHOW_ALL':
        return todos
      case 'SHOW_COMPLETED':
        return todos.filter(t => t.completed)
      case 'SHOW_ACTIVE':
        return todos.filter(t => !t.completed)
    }
  }
)

...
const visibleTodos = useSelector(getVisibleTodos)
...

Sử dụng sao cho tối ưu?

Vì useSelector dùng phép so sánh === nên nếu hàm selector trả về mảng (dùng .map.filter, destructuring ...), component sẽ bị trigger re-render.

Để ý, khi function dùng làm selector có thể có nhiều tính toán, transform phức tạp. Với mỗi lần re-render, sẽ tốn thời gian để thực thi hàm selector.

const selectData = state => {
    const filteredData = expensiveFiltering(state.data);
    const sortedData = expensiveSorting(filteredData);
    const transformedData = expensiveTransformation(sortedData);
    return transformedData;
};
...
const data = useSelector(selectData);

Trong lúc re-render, dù cho data không thay đổi, hàm selectData vẫn được gọi.

Giải quyết bằng cách sử dụng thư viện Reselect, nó sẽ cho phép trả về kết quả trước đó, nếu input là giống nhau.

import React from 'react'
import { useSelector } from 'react-redux';
import { createSelector } from 'reselect';

const selectUsers = state => state.users;

const selectData = createSelector(
    state => state.data,
    data => {
        const filteredData = expensiveFiltering(data);
        const sortedData = expensiveSorting(filteredData);
        const transformedData = expensiveTransformation(sortedData);
        return transformedData;
    }
);

export const UsersCounter = () => {
    ...
    const data = useSelector(selectData);
    ...
}

Selector phụ thuộc vào giá trị prop của component

Trong trường hợp một hàm selector có nhận input là prop của component, phải đảm bảo hàm selector được khai bao bên ngoài component.

import React from 'react';
import { useSelector } from 'react-redux';
import { createSelector } from 'reselect';

const selectUser = (state, userId) => users.find(user => user.id === userId);

const selectUserById = createSelector(
  [selectUser],
  user => expensiveTransformation(user)
);

export const UserDetails = ({ userId }) => {
  const user = useSelector(state => selectUserById(state,userId));
  return <div>{user.name}</div>
};

export const App = () => {
  return (
    <>
      <span>User Details:</span>
      <UserDetails userId={1} />
    </>
  )
};

Nhiều instance của một component

Khi một hàm selector được dùng trong nhiều instance của một component và cũng phụ thuộc vào prop, như 2 instance của UserDetails ở trên

<UserDetails userId={1} />
<UserDetails userId={2} />

Chúng ta cần chắc chắn, mỗi instance của UserDetails sẽ ứng với một instance của hàm selector, nếu chỉ viết như ví dụ ở trên là không được, cả 2 instance của UserDetails chỉ trỏ về một selector.

Sử dụng kết hợp với useMemo của React để đạt được kết quả mong muốn

import React, { useMemo } from 'react';
import { useSelector } from 'react-redux';
import { createSelector } from 'reselect';

const selectUser = (state, userId) => users.find(user => user.id === userId);

const makeSelectUserById = () => 
  createSelector(
    [selectUser],
    user => expensiveTransformation(user)
  );

export const UserDetails = ({ userId }) => {
  const selectUserMemo = useMemo(makeSelectUserById, []);
  const user = useSelector(state => selectUserMemo(state, userId));
  return <div>{user.name}</div>
};

export const App = () => {
  return (
    <>
      <span>User Details:</span>
      <UserDetails userId={1} />
	  <UserDetails userId={2} />
    </>
  )
};

Với cách này const selectUserMemo = useMemo(makeSelectUserById, []); chúng ta tạo một instance của hàm selector trên từng instance của component.

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

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

Xem thêm Việc làm it job hấp dẫn trên TopDev

Những từ cần tránh khi phát ngôn trong buổi Interview

phát ngôn
phát ngôn

Phát ngôn thật sự rất quan trong một buổi Interview. Ngoài chiếc CV IT Developer thì việc lựa chọn từ ngữ để cuộc giao tiếp với nhà tuyển dụng trở nên chuyên nghiệp hơn. Cùng TopDev xem qua đâu là những từ ngữ cần tránh trong buổi phỏng vấn.

Lo lắng

Sự lo lắng, hoang mang là cảm giác tâm lý bình thường đối với bất kỳ ứng viên nào. Dù cho bạn có kinh nghiệm dày dặn, những lo lắng vẫn có thể diễn ra. Ứng tuyển freelancer IT, nhưng bạn lại thể hiện sự lo lắng ấy ra ngoài.

Thậm chí để nó lấn át cả hoạt động cảm xúc. Và tất nhiên, bạn sẽ dễ dàng out ngay Interview kết thúc. Vì đơn giản, không một nhà tuyển dụng nào lại lựa chọn một người thiếu tự tin; mất bình tĩnh trước sự chi phối của cảm xúc.

phát ngôn
Lo lắng sẽ làm giảm sự tư tin của bạn!

Xem thêm các việc làm về tuyển dụng Data Scientist 

Điều quan trọng là bạn hãy giữ một tâm trạng tốt. Hãy nghĩ tích cực và trả lời câu hỏi phỏng vấn một cách tự nhiên nhất.

Thành thật chia sẻ:  “Tôi đang rất lo lắng” trong trường hợp này dường như là một nước cờ thiếu khôn ngoan. Do vậy, hãy cố kiểm soát và ;làm chủ cảm xúc của mình nhé!.

Các đãi ngộ về lương bổng

Lương thật sự là một yếu tố quan trọng. Và khi ứng tuyển các vị trí tuyen dung it da nang, bạn lại càng muốn biết về no hơn. Nó cũng là một quyền lợi lớn mà bạn được nhận. Tuy vậy, khi phát ngôn bạn đừng vội nhắc đến lương bổng.

Nó chỉ nên được đề cập sau khi cả 2 bên có nắm rõ các tính chất yêu cầu vị trí ứng tuyển, nhiệm vụ bạn sẽ đảm nhận. Và đặc biệt, mức lương nên được đề cập khi nhà tuyen dung it chủ động nhắc đến.

Thay vì đòi hỏi lương bổng, bạn nên cam kết về tính trách nhiệm và hiệu suất làm việc mà bạn cí thể mang lại.

Nói về những điểm yếu

Một lời khuyên dành cho bạn đó là đừng bao giờ tự khai điểm yếu hay khuyết điểm của bạn nếu như không được hỏi “Đâu là điểm yếu lớn nhất của bạn?”. Đây là lời khuyên bạn nên lưu tâm. Nếu không, ngõ cụt trong buổi phỏng vấn sẽ đến với bạn nhanh chóng.

phát ngôn
Đừng đề cập đến điểm yếu của bạn!

Thay vì nói rằng bạn thiếu cái này, thiếu cái kia, bạn nên tập trung vào việc bạn làm được gì.

Dù chỉ là những việc nhỏ, nhưng cách bạn truyển tải thông qua phát ngôn mới thật sự quan trọng. Phát ngôn cần phải có chiến lược, và nó có thể là cả một nghệ thuật giao tiếp.

I need… – Tôi cần

Phỏng vấn là buổi chia sẻ để lắng nghe, trao đổi nhiều hơn từ 2 phía. Nhà tuyển dụng họ có quyền đưa ra các yêu cầu họ cần để xem bạn có là nhân tố phù hợp hay không?

Hãy hạn chế từ “tôi cần” vì bạn không phải “chủ nhà” trong buổi phỏng vấn. Do đó mà phát ngôn của bạn cần cẩn trọng, tránh những đòi hỏi quá mức.

Xem thêm các việc làm NTQ Solution tuyển dụng

Việc bạn sử dụng “Tôi cần” trong phát ngôn còn bắt nguồn từ việc bạn muốn đề cập với nhà tuyển dụng về các đặc quyền. Đó cũng là những mong muốn của bạn.

Tuy nhiên, bạn không biết rằng phát ngôn ấy vô tình tạo ra rào cản lớn. Đặc biệt, nhà tuyển dụng sẽ cho rằng bạn đi làm chỉ vì hưởng các lợi ích, phúc lợi mà thiếu đi sự cầu thị, nhiệt huyết trong chính công việc của mình.

Có thể bạn quan tâm

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