Home Blog Page 208

Những sự thật ít người biết tới về nghề lập trình

Khi nói đến lập trình viên máy tính ta thường nghĩ tới những người khô khan, tối ngày chỉ biết ngồi bên máy tính. Nhưng sự thực có phải như vậy? Hãy cùng tìm hiểu công việc này trong chia sẻ dưới đây của David Veksler, một kỹ sư công nghệ thông tin về những sự thật ít ai biết đến trong giới lập trình viên

  1. Chỉ 10-20% thời gian của toàn bộ dự án được các lập trình viên sử dụng để viết code

Và bất kể trình độ, mỗi ngày 1 lập trình viên chỉ viết trung bình từ 10-20 dòng code. Sự khác biệt giữa tay chuyên và gà mờ đó là tay chuyên thì dành 90% thời gian để suy luận, tìm tòi và thử nghiệm các phương án tối ưu nhất cho mình; còn những gà mờ thì dành 90% thời gian để debug, thay đổi vài chỗ trong code, lại debug và mong đến một lúc nào đó chương trình sẽ hoạt động.

  1. Một lập trình viên tốt cho năng suất gấp 10 một lập trình viên tầm trung.

Một lập trình viên giỏi có thể còn hơn nữa, 20 cho đến 100 lần tùy hoàn cảnh. Đây là một sự thật không hề “gió” và đã được khoa học chứng minh từ tận những năm 60. Còn một lập trình viên tồi thì chung quy hiệu suất bằng không – chẳng làm nên chuyện gì, ngược lại vẽ ra nhiều vấn đề rối tinh rối mù cho người khác phải bận tâm sửa hộ.“Một công nhân có kĩ thuật tiện cao siêu có thể giá trị gấp vài lần một công nhân với kĩ thuật trung bình. Nhưng một lập trình viên giỏi thì có giá trị gấp 10,000 lần một lập trình viên với trình độ trung bình.” – Bill Gates

  1. Các lập trình viên giỏi thường không dành nhiều thời gian để code

Trái lại những người code liên tục từ lúc này sang lúc khác lại là những người lười biếng, vô tâm, kiêu ngạo và ít chịu tìm tòi nhất. Người lập trình tốt là người biết vận dụng linh hoạt mọi giải pháp mình từng vận dụng qua cho mọi vấn đề họ gặp phải; người lập trình tồi là người viết nên những đoạn code dài dòng, rắc rối, bố cục lung tung và khó để chỉnh sửa. Thực ra quẳng hết mớ code hỏng ra ngoài và bắt đầu lại từ đầu lại là một lựa chọn hữu ích hơn ngồi ì ạch sửa từng chút một.

  1. Định luật Entropy bao hàm mọi vật.

Entropy là một hàm biểu thị mức độ hỗn loạn của một sự kiện diễn ra trong vô số các khả năng ngẫu nhiên có thể diễn ra. Trong lập trình, thay đổi liên tục sẽ dẫn đến phá vỡ mô hình nguyên bản của thiết kế, dẫn đến sự suy giảm giá trị phần mềm (software rot). Dẫu biết điều này là không thể tránh khỏi, song các lập trình viên không nắm bắt được hình mẫu sơ khai của dự án và biết cách biến nó thành hiện thực sẽ tạo ra những phần mềm thất bại đến nỗi giá trị đã tiêu hao sạch sẽ kể cả trước khi dự án hoàn thành, và đây thường là lý do phổ biến nhất tạo nên các phần mềm thất bại (Lí do phổ biến thứ nhì là tạo ra những giá trị mà khách hàng không cần đến).

5. Mặc dù hầu hết các phần mềm đều được xây dựng bởi các đội ngũ chứ không riêng gì ai, nhưng đó cũng không phải là một hoạt động mang tính dân chủ. 

Thường thì chỉ có một người duy nhất chịu trách nhiệm về thiết kế, còn lại cả đội nghĩ cách lấp đầy cách khoảng trống xuất hiện. Kết cấu này giống với một tổ ong hay kiến nhiều hơn.

6. Lập trình là việc của những người chăm chỉ, trong đó, đặc biệt là bộ não sẽ phải hoạt động điên cuồng.

Những lập trình viên tốt nghĩ về công việc của mình 24/7. Họ viết ra những dòng code tuyệt vời nhất trong bồn tắm hay những giấc mơ. Tại sao? Bởi hầu hết các công việc quan trọng đều không được hoàn thành tại chính nơi làm việc của nó, bản thân Einstein cũng đã tháo gỡ nút thắt trong thuyết tương đối của mình khi mơ. Làm phần mềm không phải đơn giản chỉ cần dành nhiều thời gian làm việc hay thêm người vào là có thể hoàn thành.

Nguồn: Obsmedia

Sự trỗi dậy của Conversional Website

Phương thức sử dụng Conversational Interface như một vũ khí bí mật để cá nhân hóa trải nghiệm website tối đa

Internet đã giúp chúng ta truy cập nhanh chóng đến lượng lớn thông tin trong tầm tay. Tuy nhiên, không giống như máy tính, bộ não con người có khả năng xử lý hạn chế, điều này buộc chúng ta phải lọc ra các nội dung không liên quan. Điều này cho thấy khả năng chú ý của con người đang ngày càng suy giảm và giờ còn ngắn hơn cả cá vàng!

Từ sản xuất hàng loạt đến Hyper Personnalization

Trong quá khứ, hầu hết các doanh nghiệp đang hoạt động với mô hình sản xuất hàng loạt với sự đi đầu của Henry Ford, đảm bảo chất lượng sản phẩm và cung cấp cho khách hàng theo quy mô. Người tiêu dùng ngày nay có nhiều lựa chọn hơn bao giờ hết ở bất kỳ loại sản phẩm nào (bán lẻ, tài chính, phần mềm, vv) làm cho sản xuất hàng loạt không còn là một lợi thế cạnh tranh.

Trong những năm gần đây, nhờ vào sự tiến bộ của công nghệ, các doanh nghiệp đang bắt đầu áp dụng một phương pháp mới gọi là Hyper Personalization (HP)

Tâm điểm của nó, Hyper-Personalization có nghĩa là cân nhắc sự tương tác của khách hàng ở cấp độ 1:1, nơi chúng tôi xem mọi khách hàng một như một cá nhân và thiết kế một trải nghiệm tùy biến cho mỗi khách hàng riêng. Ví dụ điển hình của HP là tính năng tùy chỉnh website của Nike cho phép người dùng thiết kế giày của riêng họ.

Hyper-personalization trên Website

Chúng ta có thể thấy rằng nhiều ngành công nghiệp đang dần chuyển đổi sâu sắc nhờ vào Hyper-Personalization. Hãy xem kĩ Website, một trong những kênh truyền thông chính dùng để giao tiếp với khách hàng.

Một số công ty giả mạo đã và đang thực hiện một số mức độ cá nhân hóa trên website của họ:

Sử dụng IP address.

Nếu chúng ta nhìn vào trang chủ của Stripe, nền tảng thanh toán trực tuyến hàng đầu hiện nay, ngoại trừ thiết kế đẹp, có thể thấy rằng Stripe cung cấp các logo khách hàng khác nhau làm chứng thực dựa trên địa chỉ IP của người dùng. Dưới đây bạn có thể thấy sự khác biệt giữa những gì người dùng tại Tây Ban Nha và Mỹ thấy tại trang web của họ.

Logos dành cho người dùng tại Spain

Logos dành cho người dùng tại Mỹ

Sử dụng ngôn ngữ trình duyệt

Cùng xem website của Uber. Ta có thể thấy rằng họ theo dõi ngôn ngữ mà trình duyệt của bạn đang dùng và hiển thị nội dung được dịch sao cho phù hợp. Dưới đây là một so sánh giữa bản tiếng Tây Ban Nha và tiếng Anh.

Phiên bản website tiếng Tây Ban Nha

Phiên bản webiste tiếng Anh

Chúng ta có thể nhận ra Uber không chỉ dịch văn bản mà còn thay đổi thiết kế trang web để thích nghi tốt hơn với khán giả trong từng phiên bản.

Sử dụng referral link

Ví dụ cuối cùng là trang giới thiệu từ Intercom. Chris Von Wilpert nắm giữ vai trò quan trọng về chiến lược phát triển của Intercom. Tip đầu tiên ông đưa ra là chiến lược giới thiệu được sử dụng bởi Intercom với Dynamic Keyword Insertion. Khi người dùng nhấp vào referral link từ một cuộc trao đổi trực tiếp với brand của Intercom, không giống như các công ty SaaS khác, ông sẽ dẫn đến trên một trang đích như dưới đây.

Landing page với dynamic keyword insertion

Bí quyết ở đây là tên công ty trong thông báo thay đổi phụ thuộc vào nơi mà người dùng nhìn thấy liên kết, điều này mang lại bối cảnh tốt hơn cho người dùng do chuyển đổi nhiều hơn bằng cách sử dụng một thông điệp chung chung.

Tại sao việc áp dụng hyper-personalization vẫn còn quá chậm trên các website?

Câu trả lời là do nhiều thách thức kỹ thuật mà các trang web phải đối mặt để mang lại nhiều trải nghiệm người dùng hơn. Một số thách thức phổ biến là:

  • Dữ liệu non-actionable dư thừa. Các công ty có lượng dữ liệu phong phú nhưng không thể dùng để cá nhân hoá các trải nghiệm số bởi vì dữ liệu được chứa trong các hệ thống khác nhau.
  • Nắm rõ đối tượng để personalize. Nội dung bị khóa trong Content Management System (hệ thống quản lý nội dung) và được kiểm soát bởi các nhà phát triển, trong khi dữ liệu khách truy cập không có sẵn cho việc xác định mục tiêu theo thời gian thực.
  • Đo lường tác động của việc cá nhân hóa. Thậm chí nếu họ có thể xác định nội dung được cá nhân hoá đến các đối tượng có giá trị, các công ty thường thiếu các phương thức trực tiếp để đo lường hiệu quả tổng hợp của danh mục nội dung tùy chỉnh trên website theo thời gian.

Sự trỗi dậy của giao diện Conservational

Tin tốt là với sự nổi lên của Conversational Interface (CI) còn được gọi là giao diện dựa trên chatbot, bây giờ chúng ta có giải pháp hoàn hảo để mang lại trải nghiệm của website đến cấp độ tiếp theo.

Đối với những người không quen với thuật ngữ:

Giao diện đàm thoại là giao diện người dùng tương tác với người dùng khác kết hợp chat, âm thoại voice hoặc bất kỳ giao diện ngôn ngữ tự nhiên nào với các phần tử đồ hoạ như button, hình ảnh, menu, video, …

Slack là một ví dụ tuyệt vời cho Conversational Interface

Có ba lý do chính tại sao CI có sự phù hợp tự nhiên cho hyper-personalization trên website:

Real-time: Không giống như giao diện người dùng đồ họa tương đối tĩnh, người dùng của CIcó thể có tương tác trong thời gian thực. Hơn nữa, họ có thể chọn mỗi tương tác thông tin có liên quan nhất. Do đó, conversational interface liên tục được điều chỉnh và xác định lại bởi mỗi đầu vào từ người dùng.

-Contextualization: một cuộc trò chuyện là giao tiếp hai chiều, người dùng đang nhận được thông tin nhưng đồng thời cũng cung cấp dữ liệu của bản thân cho hệ thống: thông tin, sở thích, vị trí,… Với CI, các doanh nghiệp có thể mô tả người dùng và sử dụng tất cả các dữ liệu để cá nhân hoá những trải nghiệm hơn nữa.

-Simplicity: cuối cùng nhưng không kém phần quan trọng, với hầu hết CMS có sẵn trên thị trường, rất khó để làm được mức độ hyper-personalization thực sự cần thiết để cung cấp một trải nghiệm Frictionless. Tuy nhiên, trong trường hợp của CI, chi phí phát triển là phải thực sự phải chăng. Trên thực tế, có những dịch vụ sẵn có như Landbot.io có thể giúp mọi người xây dựng trải nghiệm đàm thoại trên trang web mà không có bất kỳ kiến thức kỹ thuật nào.

Ví dụ cho Conversional Website

Để kết luận tôi muốn chia sẻ một số ví dụ thú vị của các trang web đàm thoại:

Landbot.io: một công cụ đơn giản nhằm mục đích nhân bản hóa trải nghiệm website bằng các cuộc trò chuyện. Để chứng minh tiềm năng của CI, nhóm Landbot đã xây dựng trang web hoàn chỉnh của họ theo một định dạng cuộc trò chuyện.

Adrian Zumbrunnen: là một nhà thiết kế UX / UI, ông đã biến trang cá nhân của mình thành một cuộc trò chuyện. Ông cũng đã viết một số bài học thú vị về thí nghiệm của mình.

Upcoming Page: Sản phẩm Hunt, nền tảng chất lượng cao, gần đây tung ra các sản phẩm số mới đã phát hành một tính năng mới gọi là Upcoming Page. Nó giúp các nhà sản xuất sản phẩm để có được người dùng đầu cho các sản phẩm sắp tới của họ.

Tôi hy vọng bài viết này có thể làm rõ một số thách thức mà các nhà phát triển web đang phải đối mặt liên quan đến Hyper-Personalization. Ngoài ra, tiềm năng của Conversational Interface để làm cho trải nghiệm trên website trở còn là trở ngại.

Nguồn: TopDev via Uxplanet

Cách thức hoạt động của Javascript: Tổng quan về engine, runtime & call stack

javascript

Các Tech teams hiện nay đang khai thác tối đa mọi sự hỗ trợ của Javascript ở nhiều cấp độ trong stack của team như Frontend, Backend, Hybrid apps, các thiết bị nhúng…

Bài viết này sẽ mở đầu cho series nghiên cứu sâu về Javascript, cách thức hoạt động của Javascript, tích lũy từ quá trình nắm rõ các building blocks của Javascript và cách kết hợp chúng để viết code & apps tốt hơn.

Như đã thấy trong GitHut stats, JavaScript nằm top đầu trong Active Repositories và Total Pushes trên GitHub.

Nếu các dự án đang ngày càng trở nên độc lập hơn với JavaScript, đồng nghĩa là developer phải tận dụng mọi thứ mà Javascript & hệ sinh thái cung cấp với sự thấu hiểu ngày càng sâu hơn về những yếu tố nội bộ nhằm xây dựng nên 1 phần mềm tốt hơn.

Có rất nhiều developer đang sử dụng Javascript mỗi ngày nhưng lại không nắm được kiến thức cơ bản.

Tổng quan

Hầu hết mọi người đều đã nghe đến V8 Engine và hầu hết mọi người đều biết Javascript là single-thread hoặc biết rằng Javascript đang sử dụng 1 callback queue.

Trong post này, chúng ta sẽ đào sâu các concepts này và giải thích rõ cách hoạt động của Javascript. Nắm được chi tiết những điều này, bạn sẽ có thể viết được các ứng dụng tốt hơn, không bị block và khai thác các APIs đã cung cấp 1 cách phù hợp.

Nếu bạn mới tiếp xúc với Javascript, bài viết này sẽ giúp bạn hiểu lý do tại sao Javascript khá “kì quặc” so với các ngôn ngữ khác.

Và nếu bạn là 1 developer Javascript kinh nghiệm thì hy vọng tôi có thể đem đến vài insights tươi mới liên quan đến Javascript Runtime mà bạn đang sử dụng hằng ngày.

JavaScript Engine

Ví dụ phổ biến của JavaScript Engine là V8 engine của Google. Ví dụ, V8 engine được sử dụng trong Chrome và Node.js. Đây là tổng quan đơn giản về Javascript Engine.

Engine sẽ gồm 2 components chính:

  • Memory Heap — nơi diễn ra memory allocation
  • Call Stack — nơi các stack frames tồn tại khi code của bạn thực thi

Xem thêm các tin đăng tuyển dụng lập trình viên javascript trên TopDev

Runtime

Có các APIs trong hệ điều hành được hầu hết các JavaScript developer sử dụng ngoài kia (như “setTimeout”). Tuy nhiên, các API đó không do Engine cung cấp.

Vậy chúng đến từ đâu?

Thực tế sẽ phức tạp hơn.

Như vậy, chúng ta đã có Engine nhưng thực sự có nhiều thứ khác nữa, như Web APIs được cung cấp bởi các hệ điều hành như DOM, AJAX, setTimeout…

Và sau đó, chúng ta có event loop & callback queue rất phổ biến.

Call Stack

JavaScript là ngôn ngữ lập trình single-threaded, đồng nghĩa là nó có Call Stack single.

Call Stack là 1 data structure ghi lại nơi chúng ta hiện diện trong program. Nếu nói về 1 function, chúng ta đặt nó lên đầu stack. Nếu chúng ta trả về từ 1 function, thì lấy nó ra khỏi phần đầu. Đó chính là tất cả những gì mà stack có thể làm.

Cùng xem ví dụ sau.

function multiply(x, y) {
    return x * y;
}
function printSquare(x) {
    var s = multiply(x, x);
    console.log(s);
}
printSquare(5);

Khi engine bắt đầu thực hiện đoạn code này, Call Stack sẽ trống. Sau đó, các bước tiếp theo sẽ như sau:

Mỗi entry trong Call Stack được gọi là 1 Stack Frame.

Và đây chính xác là cách xây dựng các stack traces khi 1 exception đang được “ném” – về cơ bản nó là state của Call Stack khi exception xảy ra. Xem đoạn code sau:

function foo() {
    throw new Error('SessionStack will help you resolve crashes :)');
}
function bar() {
    foo();
}
function start() {
    bar();
}
start();

Nếu đoạn code được thực thi trong Chrome (giả định code này nằm trong file tên là foo.js), stack trace theo sau sẽ được xây dựng như sau:

Blowing the stack”  xảy ra khi bạn đến được kích cỡ Call Stack tối đa. Và việc này diễn ra khá dễ dàng đặc biệt là trong trường hợp đang sử dụng giải thuật đệ quy mà không test code quá rộng rãi. Cùng xem đoạn code mẫu:

function foo() {
    foo();
}
foo();

Khi engine bắt đầu thực thi đoạn code này, engine sẽ bắt đầu bằng việc gọi function “foo”. Tuy nhiên, function này là đệ quy và bắt đầu tự call mà không có bất kì điều kiện chấm dứt nào. Vì vậy, ở mỗi bước execution, function tương tự sẽ được thêm vào Call Stack hết lần này đến lần khác.

Tuy nhiên, trong vài thời điểm, số lượng function calls trong Call Stack sẽ vượt quá kích thước thực sự của Call Stack và hệ điều hành sẽ quyết định hành động bằng cách ném 1 error trông như này:

Chạy code trong single thread khá dễ vì bạn không phải xử lý các tình huống phức tạp phát sinh trong những môi trường multi-threaded —chẳng hạn như deadlocks.

Tuy nhiên, chạy trong 1 single thread cũng có giới hạn của nó. Vì JavaScript có 1 single Call Stack, nên chuyện gì sẽ xảy ra khi mọi thứ bị chậm?

Concurrency & Event Loop

Chuyện gì xảy ra khi bạn có function calls trong Call Stack ngốn rất nhiều thời gian để xử lý? Ví dụ, thử tưởng tượng bạn muốn thực hiện vài chuyển đổi hình ảnh phức tạp trong hệ điều hành.

Vấn đề chính là khi Call Stack có các functions để thực thi, hệ điều hành không thể thực sự làm điều gì khác vì bị block. Đồng nghĩa là hệ điều hành không thể render, không thể chạy code nào khác và bị mắc kẹt. Việc này sẽ gây ra vấn đề nếu bạn muốn có fluid UIs tốt trong ứng dụng của mình.

Thêm nữa, một khi hệ điều hành bắt đầu xử lý quá nhiều tasks trong Call Stack, nó sẽ ngừng responsive trong 1 quãng thời gian khá dài. Và hầu hết các browsers sẽ hành động bằng cách đưa ra error, hỏi bạn là liệu có muốn ngừng web page này không.

Trải nghiệm người dùng không tốt chút nào, đúng không?

Vậy làm cách nào để có thể thực thi các đoạn code này mà không chặn UI & khiến cho browser không responsive nữa? Giải pháp ở đây là asynchronous callbacks giải pháp sẽ được giải thích chi tiết hơn trong Phần 2 của tutorial “How JavaScript actually works” là “Inside the V8 engine + 5 tips on how to write optimized code”.

Trong khi đó, nếu bạn đang gặp khó khăn trong việc reproduce và hiểu rõ các vấn đề diễn ra trong các ứng dụng Javascript của mình thì hãy xem qua SessionStack. SessionStack ghi lại mọi thứ trong web apps của bạn: những thay đổi của DOM, user interactions, các exceptions của JavaScript, stack traces, các network requests bị lỗi và các tin nhắn debug.

Với SessionStack, bạn có thể replay các vấn đề trong web apps như videos và quan sát mọi thứ diễn ra với user.

Bắt đầu hoàn toàn miễn phí ở đây.

 

Nguồn: TopDev via blog.sessionstack.com

Xem thêm việc làm IT lương cao trên TopDev

Câu hỏi phỏng vấn mẹo về React: Component hay element được render trong browser?

Câu hỏi phỏng vấn mẹo về React: Component hay element được render trong browser?

Bạn có thể không thích câu trả lời vì thật sự rất phức tạp.

Isn’t the word element synonymous to the word component anyway?

Câu hỏi phỏng vấn mẹo về React: Component hay element được render trong browser?

From reactjs.org

Nói một cách kỹ thuật, ReactDOM không biểu thị một React component hoặc React element trong DOM. Nó render các phần tử DOM được hỗ trợ bởi instances của component. Điều này đúng cho các thành phần của class. Đối với function component, ReactDOM chỉ tạo ra các phần tử DOM. Function elements không có các instance (có thể được truy cập với this) vì vậy khi sử dụng một function component, ReactDOM render DOM element được tạo ra từ element được trả về của function.

Những gì bạn cần hiểu ở đây là một React element khác với một DOM element. React element chỉ là mô tả của một HTML element, React component, hoặc là sự kết hợp của cả hai.

Một câu hỏi phỏng vấn hay hơn sẽ là: “Khi nào bạn sử dụng một cái gì đó giống như <MyComponent /> trong JSX, một component, element hay một instance?”

Là element nhưng không phải là DOM element, mà là React element. Đầu mối ở đây là bất kỳ JSX tag nào được dịch sang React.createElement . Nhớ, CREATE. ELEMENT.

Tuy nhiên, đối với React để tiếp tục làm việc với React element này, nó sẽ phải đưa ra một function hoặc tạo instance từ class.

Bạn có thể tìm thấy các component, element, và instance bị hòa lẫn trong các React guides và hướng dẫn trên mạng. Tôi có lỗi về việc xáo trộn những từ ngữ này, nhưng tôi nghĩ một người mới bắt đầu học về React cần phải hiểu được những điểm khác biệt quan trọng. Blog React có một bài viết về chủ đề này nhưng lại quá kỹ thuật cho người mới bắt đầu.

Bạn có thể tham khảo những định nghĩa đơn giản hơn của tôi:

  • React Component là template. Một blueprint. Một global definition. Đây có thể là function hoặc class (với một chức năng render).
  • React Element là những gì được trả lại từ các component. Đó là một đối tượng hầu như mô tả các DOM nodes mà một thành phần đại diện. Với function component, element này là đối tượng mà hàm trả về. Với class component, Element là đối tượng mà hàm trả về của function returns. Các React element lại không phải là những gì chúng ta thấy trong trình duyệt. Chúng chỉ là những đối tượng trong bộ nhớ và không thể thay đổi bất cứ điều gì.
  • React tạo, cập nhật và hủy các instance nội bộ để tìm ra DOM element tree cần phải được render cho browser. Khi làm việc với các class components, thường thì sẽ tham chiếu đến các DOM element được render bằng browser như các component instances. Bạn có thể render cho nhiều instance của cùng một component. Instance là từ khóa “this” mà bạn sử dụng bên trong các thành phần dựa trên class. Bạn sẽ không cần phải tạoinstance từ class 1 cách thủ công, chỉ cần nhớ rằng nó nằm ở một nơi nào đó trong bộ nhớ của React.
  • Các phần tử React dựa trên chức năng không có instance. Một function component vẫn có thể được render nhiều lần nhưng React không chỉ kết hợp một local instance với mỗi lần biểu thị. Nó chỉ sử dụng chức năng gọi hàm để xác định DOM element nào sẽ hiển thị cho hàm.

Điểm mấu chốt là ReactDOM không hiển thị các component trong trình duyệt, và nó không biểu thị các phần tử hoặc (theo nghĩa giữ phần tử để đại diện cho kết quả của React.createElement). Nó cũng không thể hiện instance mà thể hiện các DOM element.

Thật không may, có vẻ như có một practice phổ biến là ở đó để sử dụng term component là cả template lẫn instances hoặc invocations được sử dụng thông qua templates. Tôi không đổ lỗi cho bất cứ ai vì bị lẫn lộn ở đây. Chỉ là một chút thất vọng.

Câu chuyện ở đây là gì?

Mỗi React app bắt đầu với một render sử dụng một phần tử React. Hãy dùng ví dụ HelloMessage  từ reactjs.org, thay đổi 1 chút để có function component:

const Today = () => (
 <div>Today is {new Date().toDateString()}</div>
);
class HelloMessage extends React.Component {
 render() {
   return (
     <React.Fragment>
       <div>Hello {this.props.name}</div>
       <Today />
     </React.Fragment>
   );
 }
}
ReactDOM.render(
 <HelloMessage name="Taylor" />,
 mountNode
);

React element đầu tiên là instance chúng ta bắt đầu trong ReactDOM.render call:

<HelloMessage name="Taylor" /> // This is a React element

React element này mô tả rằng DOM tree được kết xuất nên bắt đầu với component của HelloMessage và một biến  name  với giá trị prop tương đương với Taylor.

React bây giờ cần trả lời câu hỏi: HelloMessage là gì?

Mỗi lần React element mô tả 1 React component (giống như React element chúng ta có ở trên), React sử dụng component của nó để thay thế instance đó bằng những component được trả về. Nó tạo ra instance cho các component dựa vào class hiện tại và giữ tham chiếu của instance trong bộ nhớ và không tạo ra bất cứ điều gì cho các component dựa trên chức năng; nó chỉ invoke element.

Những gì được trả lại từ component của HelloMessage là React element mô tả một  React.Fragment Component:

React ngay bây giờ cần trả lời câu hỏi:  React.Fragment là gì?

React sẽ tiếp tục giảm các mô tả không xác định của các component cho đến khi chỉ có các DOM nodes hợp lệ. Mô tả  React.Fragment được dịch sang 2 React element, một mô tả div và còn lại mô tả một thành phần Today 

React ngay bây giờ cần trả lời câu hỏi: Today  là gì?

Nó gọi hàm Today  để đưa ra câu hỏi cuối cùng này. Hàm Today  trả về một React element mô tả một div.

Tại thời điểm này, virtual tree hoàn thành với tất cả các React elements mô tả các DOM nodes. React sử dụng thuật toán đối chiếu của nó để tìm ra những gì điều được cập nhật trong browser. Các node đã được dịch với instance component duy trì hiệu quả của việc modify instance đó.

Tham khảo việc làm React lương cao mới nhất trong tháng tại đây

Nguồn: TopDev via Medium.freecodecamp

Học Python: Từ Zero đến Hero (phần 2)

PHẦN 1

Iteration: Looping thông qua Data Structures

Như đã biết về Python Basics, List iteration rất đơn giản. Các developer Pythonthường sử dụng looping For như sau:

bookshelf = [
  "The Effective Engineer",
  "The 4 hours work week",
  "Zero to One",
  "Lean Startup",
  "Hooked"
]

for book in bookshelf:
    print(book)

Vậy là với mỗi quyển trên kệ, (có thể làm mọi thứ) để print nó. Đơn giản & trực quan, đó chính là Python.

Đối với hash data structure, chúng ta cũng có thể sử dụng loop for nhưng áp dụng key :

dictionary = { "some_key": "some_value" }

for key in dictionary:
    print("%s --> %s" %(key, dictionary[key]))
    
# some_key --> some_value

Với mỗi key trong dictionary , chúng ta sẽ print key đó và value tương ứng của nó.

Cách khác là sử dụng method iteritems.

dictionary = { "some_key": "some_value" }

for key, value in dictionary.items():
    print("%s --> %s" %(key, value))

# some_key --> some_value

Chúng ta đã đặt tên 2 biến số là key & value, nhưng không cần thiết, có thể đặt bất kì tên nào. Cùng xem:

dictionary_tk = {
  "name": "Leandro",
  "nickname": "Tk",
  "nationality": "Brazilian",
  "age": 24
}

for attribute, value in dictionary_tk.items():
    print("My %s is %s" %(attribute, value))
    
# My name is Leandro
# My nickname is Tk
# My nationality is Brazilian
# My age is 24

Rõ ràng, chúng ta đã sử dụng attribute như 1 tham số cho Dictionary key & nó hoạt động rất tốt. Quá tuyệt vời!

  Học Python: Từ Zero đến Hero (phần 1)

Classes & Objects

Một chút lý thuyết

Objects là đại diện cho các đối tượng trong thực tế như xe hơi, chó, xe đạp. Các objects sẽ chia sẻ 2 đặc tính chủ chốt là: data và behavior.

Xe sẽ có data, như số các bánh xe, số cửa sổ và sức chứa chỗ ngồi. Chúng sẽ phơi bày behavior: có thể nâng lên, dừng lại, hiển thị lượng nhiên liệu còn lại…

Chúng ta nhận diện data như các attributes & behavior như các methods trong lập trình hướng đối tượng.

Data → Attributes và Behavior → Methods

Và 1 Class chính là blueprint mà từ đây các objects đơn lẻ sẽ được tạo ra. Trên thực tế, chúng ta thường tìm các objects cùng loại với nhau. Như xe hơi đề có động cơ, bánh xe, cửa… và mỗi xe được build từ cùng bộ blueprints, có cùng các components.

Python Object-Oriented Programming mode: ON

Trong vai trò 1 ngôn ngữ lập trình hướng đối tượng, Python có 3 con concepts: class & object.

Một class là 1 blueprint, 1 model cho các objects của class đó.

Nói chung, 1 class chỉ là 1 model hoặc 1 cách để define attributes và behavior (như đã đề cập trong section theory). Ví dụ, 1 phương tiên di chuyển class có attributes riêng dùng để xác định liệu objects nào là các phương tiện di chuyển. Số lượng các bánh xe, loại bồn chứa, sức chứa chỗ ngồi và vận tốc maximum đều là các attributes của 1 phương tiện di chuyển.

Từ đây, chúng ta có thể xem syntax Python cho các classes:

class Vehicle:
    pass

Chúng ta define classes với 1 class statement  – và chỉ có vậy. Dễ mà, phải không?

Objects là các instances của 1 class. Chúng ta tạo 1 instance bằng cách đặt tên cho class.

car = Vehicle()
print(car) # <__main__.Vehicle instance at 0x7fb1de6c2638>

Ở đây, car là 1 object (hoặc instance) của class Vehicle.

Lưu ý rằng phương tiện di chuyển class của chúng ta có 4 attributes: số lượng bánh xe, loại bồn chứa, sức chứa chỗ ngồi và vận tốc tối đa. Chúng ta đặt tất cả những attributes này khi tạo 1 phương tiện object. Vậy nên ở đây sẽ define class để nhận data khi khởi tạo nó:

class Vehicle:
    def __init__(self, number_of_wheels, type_of_tank, seating_capacity, maximum_velocity):
        self.number_of_wheels = number_of_wheels
        self.type_of_tank = type_of_tank
        self.seating_capacity = seating_capacity
        self.maximum_velocity = maximum_velocity

Chúng ta sử dụng method init, gọi là 1 constructor method. Vì vậy, khi tạo phương tiện di chuyển object, chúng ta có thể define những attributes này. Hãy tưởng tượng rằng bạn rất yêu thích loại Tesla Model S, và muốn tạo loại object này. Nó sẽ có 4 bánh xe, chạy năng lượng điện, gồm 5 ghế và vận tốc tối đa là 250km/giờ(155 mph). Tạo object như sau:

tesla_model_s = Vehicle(4, 'electric', 5, 250)

Bốn bánh + “loại bồn chứa” bằng điện + 5 ghế + vận tốc tối đa 250km/ giờ

Tất cả các attributes đã được thiết lập. Nhưng làm thế nào để tiếp cận được các giá trị của những attributes này? Chúng ta gửi 1 tin nhắn đến object hỏi về chúng, gọi nó là 1 method, là hành vi của object trên. Hãy implement nó:

class Vehicle:
    def __init__(self, number_of_wheels, type_of_tank, seating_capacity, maximum_velocity):
        self.number_of_wheels = number_of_wheels
        self.type_of_tank = type_of_tank
        self.seating_capacity = seating_capacity
        self.maximum_velocity = maximum_velocity

    def number_of_wheels(self):
        return self.number_of_wheels

    def set_number_of_wheels(self, number):
        self.number_of_wheels = number

Đây là 1 implementation của 2 methods: number_of_wheels và set_number_of_wheels. Chúng ta gọi nó là getter & setter. Vì getter lấy attribute value và setter thiết lập 1 giá trị mới cho attribute đó.

Trong Python, thì sử dụng @property (decorators) để define gettersvà setters.

class Vehicle:
    def __init__(self, number_of_wheels, type_of_tank, seating_capacity, maximum_velocity):
        self.number_of_wheels = number_of_wheels
        self.type_of_tank = type_of_tank
        self.seating_capacity = seating_capacity
        self.maximum_velocity = maximum_velocity

    @property
    def number_of_wheels(self):
        return self.number_of_wheels

    @number_of_wheels.setter
    def number_of_wheels(self, number):
        self.number_of_wheels = number

Và sử dụng các methods này như những attributes:

tesla_model_s = Vehicle(4, 'electric', 5, 250)
print(tesla_model_s.number_of_wheels) # 4
tesla_model_s.number_of_wheels = 2 # setting number of wheels to 2
print(tesla_model_s.number_of_wheels) # 2

Điều này có khác 1 chút với việc define methods. Các methods hoạt động như là các attributes. Ví dụ, khi set số bánh xe mới, chúng ta không áp số 2 vào thành 1 tham số mà set giá trị 2 vào number_of_wheels. Đây là 1 cách để viết code pythonic getter và setter.

Nhưng có thể sử dụng methods cho những thứ khác, như method “make_noise

class Vehicle:
    def __init__(self, number_of_wheels, type_of_tank, seating_capacity, maximum_velocity):
        self.number_of_wheels = number_of_wheels
        self.type_of_tank = type_of_tank
        self.seating_capacity = seating_capacity
        self.maximum_velocity = maximum_velocity

    def make_noise(self):
        print('VRUUUUUUUM')

Khi call method này, nó chỉ trả lại 1 string VRRRRUUUUM.

tesla_model_s = Vehicle(4, 'electric', 5, 250)
tesla_model_s.make_noise() # VRUUUUUUUM

Encapsulation: Ẩn thông tin

Encapsulation là cơ chế giới hạn khả năng tiếp cận trực tiếp đến data & methods của các objects. Nhưng cùng lúc đó, nó lại hỗ trỡ việc vận hành trên data đó (methods của các objects)

“Encapsulation được dùng để ẩn Data Members & Members function. VỚi Định nghĩa này, encapsulation đồng nghĩa là việc hiển thị nội bộ của 1 object được ẩn toàn bộ khỏi tầm nhìn của definition Đến từ Object đó” — Wikipedia

Tất cả hiển thị nội bộ của 1 object được ẩn khỏi bên ngoài. Chỉ có object đó mới tương tác được với data nội bộ của nó.

Đầu tiên, chúng ta cần phải hiểu cách hoạt động của các biến số instance public và non-public và methods.

Các biến số Instance công khai

Đối với 1 Python class, khởi tạo 1 public instance variable trong constructor method của chúng ta.

Trong method constructor:

class Person:
    def __init__(self, first_name):
        self.first_name = first_name

Ở đây, áp dụng value first_name như 1 argument đến public instance variable.

tk = Person('TK')
print(tk.first_name) # => TK

Trong class:

class Person:
    first_name = 'TK'

Không cần áp dụng first_name như 1 argument, và tất cả các instance objects sẽ có 1  class attribute được khởi tạo với TK.

tk = Person()
print(tk.first_name) # => TK

Tốt. Hiện chúng ta đã biết sử dụng public instance variables và class attributes. Điều thú vị khác nữa về phần public là có thể quản lý giá trị của biến, nghĩa là object có thể quản lý giá trị biến số của nó: các giá trị biến số Get và Set.

Nhắc đến Person, nếu muốn set giá trị khác cho biến first_name:

tk = Person('TK')
tk.first_name = 'Kaio'
print(tk.first_name) # => Kaio

Đấy, chúng ta chỉ set giá trị khác (kaio) cho biến instance first_name và nó đã cập nhật giá trị. Đơn giản vậy thôi. Vì là biến public nên sẽ làm được điều đó.

Biến Instance không công khai

“Ở đây, chúng ta không sử dụng thuật ngữ “private” vì không có attribute nào thực sự riêng tư trong Python (mà  không có 1 lượng lớn công việc không cần thiết)” — PEP 8

Giống như public instance variable , chúng ta có thể define non-public instance variable trong method constructor hoặc trong class. Điểm khác biệt syntax chính là: đối với non-public instance variables, sẽ sử dụng gạch dưới (_) trước tên variable.

“‘Các biến instance private mà không thể tiếp cận ngoài trừ lúc ở trong 1 object thì sẽ không tồn tại trong python. Tuy nhiên, có 1 quy ước được hầu hết code python theo là: 1 name prexide với 1 dấu gạch dưới (như: _spam) nên được xem như 1 phần không công khai của API (dù nó là 1 function, 1 method hay 1 data member)” — Python Software Foundation

Ví dụ:

class Person:
    def __init__(self, first_name, email):
        self.first_name = first_name
        self._email = email

Bạn có thấy biến email không? Đây là cách chúng ta define 1 non-public variable

tk = Person('TK', 'tk@mail.com')
print(tk._email) # tk@mail.com

“Chúng ta có thể access & cập nhật nó. Non-public variables chỉ là 1 Quy ước và nên được xem như phần non-public của API”

Vì vậy, sử dụng 1 method cho phép define trong class definition. Cùng implement 2 methods (email và update_email) để hiểu rõ hơn:

class Person:
    def __init__(self, first_name, email):
        self.first_name = first_name
        self._email = email

    def update_email(self, new_email):
        self._email = new_email

    def email(self):
        return self._email

Bây giờ chúng ta có thể update & access non-public variables bằng những methods đó. Cùng xem:

tk = Person('TK', 'tk@mail.com')
print(tk.email()) # => tk@mail.com
tk._email = 'new_tk@mail.com'
print(tk.email()) # => tk@mail.com
tk.update_email('new_tk@mail.com')
print(tk.email()) # => new_tk@mail.com
  1. Khởi tạo 1 object mới bằng first_name TK và email tk@mail.com
  2. Printt email bằng cách tiếp cận non-public variable với 1 method
  3. Cố gắng set email mới ngoài class
  4. Cần phải xem non-public variable như phần non-public của API
  5. Cập nhật non-public variable bằng method instance
  6. Thành công! Chúng ta có thể cập nhật nó trong class bằng method helper

Public Method

Với public methods, chúng ta cũng có thể sử dụng ngoài class:

class Person:
    def __init__(self, first_name, age):
        self.first_name = first_name
        self._age = age

    def show_age(self):
        return self._age

Thử test xem:

tk = Person('TK', 25)
print(tk.show_age()) # => 25

Tốt, vậy là không có vấn đề gì.

Non-public Method

Nhưng với non-public methods thì không làm được điều này. Hãy implement cùng class Person nhưng bây giờ với 1 show_age non-public method bằng 1 dấu gạch dưới (_).

class Person:
    def __init__(self, first_name, age):
        self.first_name = first_name
        self._age = age

    def _show_age(self):
        return self._age

Giờ chúng ta sẽ cố gọi non-public method này với object của mình:

tk = Person('TK', 25)
print(tk._show_age()) # => 25

“Chúng ta có thể access & Update nó. Non-public methods chỉ là 1 quy ước & nên được xem như 1 phần non-public của API”

Dưới đây là ví dụ về cách sử dụng non-public methods:

class Person:
    def __init__(self, first_name, age):
        self.first_name = first_name
        self._age = age

    def show_age(self):
        return self._get_age()

    def _get_age(self):
        return self._age

tk = Person('TK', 25)
print(tk.show_age()) # => 25

Chúng ta có 1 _get_age non-public method và 1 show_age public method. Object của chúng ta có thể sử dụng  show_age (bên ngoài class) và _get_age chỉ được sử dụng bên trong class definition (trong method show_age). Nhưng 1 lần nữa, đây chỉ là vấn đề liên quan đến quy ước.

Encapsulation Summary

Với encapsulation, có thể đảm bảo rằng hiển thị nội bộ của object được ẩn.

Inheritance: các hành vi và các đặc tính

Một vài objects nào đó sẽ sở hữu vài điểm chung: behavior & characterists của chúng.

Trong lập trình hướng đối tượng, các class có thể thừa hưởng những đặc tính (data) và hành vi (methods) tương tự từ class khác.

Cùng xem 1 ví dụ khác và implement nó bằng Python.

Hãy tưởng tượng 1 chiếc xe hơi. Số lượng bánh xe, sức chứa chỗ ngồi và vận tốc tối đa là tất cả các attributes của 1 chiếc xe. Có thể nói rằng 1 class ElectricCar thừa hưởng cùng các attributes từ class Car thông dụng.

Class Car đã implement như sau:

class Car:
    def __init__(self, number_of_wheels, seating_capacity, maximum_velocity):
        self.number_of_wheels = number_of_wheels
        self.seating_capacity = seating_capacity
        self.maximum_velocity = maximum_velocity

Một khi đã khởi tạo, chúng ta có thể sử dụng tất cả instance variables đã được tạo ra. Tốt.

Trong Python, hãy áp dụng parent class vào child class như 1 tham số. Một class ElectricCar có thể kế thừa từ class Car.

class ElectricCar(Car):
    def __init__(self, number_of_wheels, seating_capacity, maximum_velocity):
        Car.__init__(self, number_of_wheels, seating_capacity, maximum_velocity)

Đơn giản vậy thôi, chúng ta không cần phải implement bất kì method nào khác, vì class nà đã có rồi (được thừa hưởng từ class Car).

my_electric_car = ElectricCar(4, 5, 250)
print(my_electric_car.number_of_wheels) # => 4
print(my_electric_car.seating_capacity) # => 5
print(my_electric_car.maximum_velocity) # => 250

Thật đẹp, đúng không?

Tổng quan

Như vậy, bài viết này đã giúp chúng ta nắm được những kiến thức Python cơ bản:

  • Cách hoạt động của các biến Python
  • Cách hoạt động của conditional statements Python
  • Cách looping Python (while & for) hoạt động
  • Cách sử dụng Lists: Collection | Array
  • Dictionary Key-Value Collection
  • Cách lặp thông qua data structures
  • Objects & Classes
  • Các attibutes như data của objects
  • Methods như hành vi của các objects
  • Sử dụng getters và setters của Python & property decorator
  • Encapsulation: ẩn thông tin
  • Inheritance: behaviors (hành vi) và characteristics (đặc tính)

Bạn có thể đọc thêm quá trình nghiên cứu lập trình của tôi ở The Renaissance Developer.

Chúc vui, đừng quên hãy tiếp tục học hỏi và luôn cố gắng coding nhé!

Xem thêm các vị trí python tuyển dụng từ công ty lớn

Nguồn: TopDev via medium.freecodecamp.com

Học Python: Từ Zero đến Hero (phần 1)

Trước nhất, Python là gì? Theo người sáng lập, Guido van Rossum, Python là:

“Là programming language high-level, và triết lý core design tập trung vào code readability và syntax cho phép các programmers thể hiện được concepts chỉ trong vài dòng code”

Với tôi, lý do đầu tiên học Python vì đây là ngôn ngữ đẹp, có thể code & thể hiện suy nghĩ của tôi 1 cách tự nhiên.

Lý do nữa chúng tôi có thể tận dụng việc code Python trong nhiều lĩnh vực như: Data Science, Web Development, Machine Learning… Quora, Pinterest & Spotify đều dùng Python để lập trình backend Web của mình.

Tuyển python lương cao các công ty hot

Kiến thức cơ bản

1. Variables – Các biến số

Bạn có thể xem các biến số này như những từ ngữ chứa 1 giá trị.

Trong Python, rất dễ để define 1 variable và đặt giá trị cho nó. Hãy tưởng tượng bạn muốn lưu số 1 trong biến gọi là “one”. Bạn có thể làm như sau:

one = 1

Quá dễ phải không? Chỉ cần chỉ định giá trị 1 đến biến “one”.

two = 2
some_number = 10000

Và bạn có thể chỉ định bất kì giá trị nào đến bất kì biến số nào mà bạn muốn. Như đã thấy ở bảng trên, biến “two” giữ số nguyên 2, và “some_number” giữ 10,000.

Bên cạnh các số nguyên, chúng ta cũng có thể sử dụng booleans (True / False), strings, float, và rất nhiều kiểu dữ liệu khác.

# booleans
true_boolean = True
false_boolean = False

# string
my_name = "Leandro Tk"

# float
book_price = 15.80

2. Control Flow: conditional statements (lệnh tùy điều kiện)

If” sử dụng 1 expression để xác định liệu statement là True hay False. Nếu là True, nó sẽ thực thi những gì thuộc về lệnh “if”. Ví dụ:

if True:
  print("Hello Python If")

if 2 > 1:
  print("2 is greater than 1")

2 lớn hơn 1, vì vậy code “print” sẽ được thực thi.

Lệnh “else” sẽ được thực thi nếu expression “if” là false.

if 1 > 2:
  print("1 is greater than 2")
else:
  print("1 is not greater than 2")

1 không lớn hơn 2, nên code trong “else” statement will be executed.

Bạn cũng có thể sử dụng statement “elif”:

if 1 > 2:
  print("1 is greater than 2")
elif 2 > 1:
  print("1 is not greater than 2")
else:
  print("1 is equal to 2")

3. Looping / Iterator

Trong Python, chúng ta có thể iterate theo nhiều hình thức khác nhau, như while và for.

While Looping: nếu statement là True, thì code trong block sẽ được thực thi. Vì vậy, code này sẽ in số từ 1 đến 10.

num = 1

while num <= 10:
    print(num)
    num += 1

Loop while cần 1 “loop condition.” Nếu True, nó sẽ tiếp tục lặp. Trong ví dụ này, khi num là 11 loop condition sẽ bằng False.

Một đoạn code căn bản khác mà bạn cần hiểu chính là:

loop_condition = True

while loop_condition:
    print("Loop Condition keeps: %s" %(loop_condition))
    loop_condition = False

Loop condition là True nên nó sẽ tiếp tục lặp — cho đến khi chúng ta set nó False.

For Looping: bạn áp dụng biến “num” cho block này, và lệnh “for” sẽ lặp nó cho bạn. Đoạn code này sẽ print tương tự như while code: từ 1 đến 10.

for i in range(1, 11):
  print(i)

Bạn thấy không? Rất đơn giản. Vùng sẽ bắt đầu với 1 và kéo dài đến element thứ 11 (10 là element số thứ tự 10).

  Hướng dẫn cài đặt, lập trình Python trên Ubuntu (Linux)

List: Collection | Array | Data Structure

Tưởng tượng bạn muốn lưu số nguyên 1 trong 1 biến số. Nhưng có thể bây giờ bạn lại muốn lưu 2. Và 3, 4, 5 …

Liệu tôi có cách nào khác để lưu tất cả các số nguyên mà tôi muốn, nhưng không phải trong hàng triệu biến số? Tất nhiên là có 1 cách như thế.

List là 1 collection được dùng để lưu danh sách các giá trị (như những số nguyên mà bạn muốn).

my_integers = [1, 2, 3, 4, 5]

Rất đơn giản, chúng ta có thể tạo 1 array & lưu nó trong my_integer.

Nhưng bạn sẽ tự hỏi: “Làm thế nào để lấy 1 giá trị từ array này?”

Một câu hỏi thú vị. List có 1 concept gọi là index. Element đầu tiên sẽ lấy index 0 (zero). Element tiếp theo lấy 1 và cứ như thế.

Để rõ ràng hơn, chúng ta có thể diễn tả array & mỗi element với index của nó.

Sử dụng Python syntax sẽ rất dễ hiểu:

my_integers = [5, 7, 1, 3, 4]
print(my_integers[0]) # 5
print(my_integers[1]) # 7
print(my_integers[4]) # 4

Tưởng tượng xem, bạn không muốn lưu trữ các số nguyên, bạn chỉ muốn lưu trữ strings, như danh sách họ tên của những người thân quen. Đoạn code của tôi sẽ như thế này:

relatives_names = [
  "Toshiaki",
  "Juliana",
  "Yuji",
  "Bruno",
  "Kaio"
]

print(relatives_names[4]) # Kaio

Nó sẽ hoạt động tương tự như các số nguyên.

Chúng ta chỉ mới cách hoạt động của Lists Nhưng tôi sẽ cho bạn thấy cách thêm 1 element vào data structure List (1 item vào 1 list).

Method thông dụng nhất để thêm 1 giá trị mới vào 1 List là append. Cách thức hoạt động như sau:

bookshelf = []
bookshelf.append("The Effective Engineer")
bookshelf.append("The 4 Hour Work Week")
print(bookshelf[0]) # The Effective Engineer
print(bookshelf[1]) # The 4 Hour Work Week

append cực kì đơn giản. Bạn chỉ cần áp dụng element như tham số  append (ví dụ “The Effective Engineer”)

  Học Python: Từ Zero đến Hero (phần 2)

Lists đã xong. Cùng nghiên cứu data structure khác:

Dictionary: Key-Value Data Structure

Hiện tại, chúng ta đã biết Lists được index với các số nguyên. Nhưng chuyện gì sẽ xảy ra nếu chúng ta không muốn sử dụng các số nguyên như các indices? Một số data structure có thể sử dụng là numeric, string hoặc các loại indices khác.

Cùng nghiên cứu về data structure DictionaryDictionary là tập hợp các cặp key-value. Kết quả sẽ ra thế này:

dictionary_example = {
  "key1": "value1",
  "key2": "value2",
  "key3": "value3"
}

key là index chỉ đến value. Làm thế nào để tiếp cận value Dictionary? Hãy sử dụng key.

dictionary_tk = {
  "name": "Leandro",
  "nickname": "Tk",
  "nationality": "Brazilian"
}

print("My name is %s" %(dictionary_tk["name"])) # My name is Leandro
print("But you can call me %s" %(dictionary_tk["nickname"])) # But you can call me Tk
print("And by the way I'm %s" %(dictionary_tk["nationality"])) # And by the way I'm Brazilian

Tôi đã tạo 1 Dictionary gồm tên, nickname và quốc tịch. Những attributes này đều là keys Dictionary.

Khi nghiên cứu cách tiếp cận List bằng index, chúng ta cũng sử dụng indices (keys trong context Dictionary) để tiếp cận value lưu trữ trong Dictionary.

Trong ví dụ này, tôi đã print 1 đoạn về mình bằng tất cả các giá trị lưu trong Dictionary. Khá đơn giản, phải không?

Điều khá hay về Dictionary chính là chúng ta có thể sử dụng bất cứ thứ gì làm value. Trong Dictionary mà tôi tạo, tôi muốn thêm key “age” & số tuổi nguyên thực sự của mình vào đó:

dictionary_tk = {
  "name": "Leandro",
  "nickname": "Tk",
  "nationality": "Brazilian",
  "age": 24
}

print("My name is %s" %(dictionary_tk["name"])) # My name is Leandro
print("But you can call me %s" %(dictionary_tk["nickname"])) # But you can call me Tk
print("And by the way I'm %i and %s" %(dictionary_tk["age"], dictionary_tk["nationality"])) # And by the way I'm Brazilian

Ở đây, chúng ta có 1 cặp key (tuổi) value (24) bằng string như key và integer như value.

Như những gì đã làm với Lists, cùng nghiên cứu cách thêm các elements vào 1 Dictionarykey chỉ đến 1 value là 1 phần quan trọng tạo nên Dictionary. Điều này cũng đúng khi chúng ta đề cập đến việc thêm các elements vào đó:

dictionary_tk = {
  "name": "Leandro",
  "nickname": "Tk",
  "nationality": "Brazilian"
}

dictionary_tk['age'] = 24

print(dictionary_tk) # {'nationality': 'Brazilian', 'age': 24, 'nickname': 'Tk', 'name': 'Leandro'}

Chúng ta chỉ cần chỉ định 1 value vào 1 key Dictionary. Không có gì phức tạp, đúng không nhỉ?

(còn tiếp)

Nguồn: TopDev via medium.freecodecamp.org

Ứng tuyển các vị trí tuyển dụng IT lương cao trên TopDev

Những điều cần biết về CSS-in-JS

Thinking in components — Bạn sẽ không còn phải maintain 1 đống style-sheets nữa. CSS-in-JS sẽ trích xuất model CSS theo level component, thay vì theo level document (modularity).

Ví dụ về Styled React Component


Nhiều khả năng là bạn đã nghe đến những thuật ngữ như CSS-in-JSStyled ComponentsRadiumAphrodite & tự hỏi tại sao lại có thứ này nữa?—Tôi đã & đang rất hài lòng với CSS-in-CSS (CSS trong .css)”

CSS-in-JS là 1 topic nhạy cảm, gây nhiều tranh cãi, được xem là concept tốt nhất giúp bạn không cần phải maintain folder chứa đầy các stylesheet.

Xem qua CSS-in-JS.


CSS-in-JS là gì?

JSS là abstraction mạnh mẽ hơn CSS. JSS sử dụng JavaScript như 1 ngôn ngữ để mô tả các styles theo cách declarative & maintainable. JSS là JS high performance đến CSS compiler hoạt động ở runtime & server-side. CORE LIBRARY THUỘC LEVEL THẤP & framework agnostic, NẶNG khoảng 6KB (ĐÃ minified & gzipped) Có thể extensible bằng plugins API. — nguồn

Nhớ rằng Inline styles & CSS-in-JS không giống nhau! Chúng hoàn toàn khác nhau !

Cách thức hoạt động của Inline Styles

const textStyles = {
  color: white,
  backgroundColor: black
}

<p style={textStyles}>inline style!</p>
inline styles

Trong hệ điều hành, việc này sẽ dính vào DOM node như thế này:

<p style="color: white; backgrond-color: black;">inline style!</p>

Cách thức hoạt động của CSS-in-JS

import styled from 'styled-components';

const Text = styled.div`
  color: white,
  background: black
`

<Text>Hello CSS-in-JS</Text>

Trong browser, đoạn code này sẽ attach với DOM như thế này:

<style>
.hash136s21 {
  background-color: black;
  color: white;
}
</style>

<p class="hash136s21">Hello CSS-in-JS</p>

Sự khác biệt

Bạn có nhận ra sự khác biệt nào không? CSS-in-JS gắn tag <style>  ở phần trên của DOM trong khi inline styles chỉ gắn properties vào DOM node.

Tại sao việc này lại quan trọng?

Không phải tất cả các tính năng CSS đều có thể ẩn danh trước event handlers của Javascript, nhiều selectors ngụy tạo (như :disabled:before:nth-child) đều không hoạt động, styling các tags html và body không được hỗ trợ…

Với CSS-in-JS, bạn nắm giữ hết mọi quyền năng của CSS trong lòng bàn tay. Vì CSS đã được generate, bạn có thể sử dụng mọi truy vấn media & selector ngụy tạo mà bạn có thể nghĩ đến. Một vài thư viện (như jssstyled-components) thậm chí còn hỗ trợ các tính năng không thuộc CSS là nesting!

Bài viết trong link sau sẽ giải thích chi tiết hơn về điểm khác biệt

“Chỉ cần viết CSS in CSS và xong!”

Đúng vậy— tuy trường hợp này đã xảy ra từ lâu rồi nhưng thách thức đặt ra lúc này chính là modern web được viết bằng components, không phải pages.

CSS chưa bao giờ phù hợp với các giải pháp bằng component. CSS-in-JS sẽ thực sự giải quyết được vấn đề này. Vue cũng là 1 giải pháp khác dù styles của Vue không tiếp cận với components state.

Lợi ích của việc sử dụng CSS-in-JS là gì?

  • Thinking in components — Bạn sẽ không còn phải maintain quá nhiều style-sheets nữa. CSS-in-JS sẽ trích xuất model CSS ở cấp độ component, thay cho cấp độ document (phương pháp modularity).
  • CSS-in-JS sẽ khai thác tối đa hệ sinh thái JavaScript nhằm tăng cường cho CSS.
  • True rules isolation” — Các selector được scoped là không đủ. Nếu không define rõ, CSS sẽ có các properties được tự động kế thừa từ element parent. Nhờ có plugin jss-isolate, các nguyên lý JSS sẽ không kế thừa properties.
  • Scoped selectors — CSS chỉ có 1 global namespace. Bạn sẽ không thể tránh khỏi các va chạm selector trong các non-trivial apps. Đặt tên các conventions như BEM có thể giúp ích trong 1 dự án nhưng sẽ khi tích hợp code bên thứ 3 thì mọi chuyện sẽ khác. Trong khi đó, JSS sẽ mặc định generate các class names unique khi JSS compile hiển thị JSON representation sang CSS.
  • Vendor Prefixing —CSS rules được tự động vendor prefix
  • Code sharing — Dễ dàng chia sẻ constants & functions giữa JS và CSS.
  • Chỉ có các styles hiện đang được sử dụng trên màn hình của bạn mới có trong DOM.
  • Dead code elimination
  • Unit tests cho CSS!

Bất lợi của CSS-in-JS?

  • Learning curve – Đường cong học tập: những nỗ lực cần thiết để học được kĩ năng mới sau một khoảng thời gian nhất định
  • Các dependencies mới
  • Các thành viên mới trong team sẽ gặp khó khăn để thích nghi với code-base. Những ai mới làm quen với front-end sẽ phải học nhiều thứ mới.
  • Không hoàn toàn là điểm bất lợi nhưng CSS-JS sẽ thách thức status quo. (tình trạng ngưng trệ trước khi có những tác động tạo ra sự thay đổi)

Vì các điểm mạnh vẫn vượt trội điểm yếu nên hãy thử CSS-in-JS xem sao nhé! Chẳng có gì để mất!


Các thư viện CSS-in-JS phổ biến nhất

Styled Components

import React, { Component } from 'react';
import styled from 'styled-components';

const Title = styled.h1`
  color: white;
`;

const Wrapper = styled.div`
    background: black
`

class App extends Component {
  render() {
    return (
        <Wrapper>
            <Title>Hello World!</Title>
        </Wrapper>
    );
  }
}

export default App;

JSS-React

import React from 'react'
import injectSheet from 'react-jss'

const styles = {
    wrapper: {
        background: 'black'
    },
    title: {
        color: 'white'
    }
}


const App = ({classes}) => (
    <div className={classes.wrapper}>
        <h1 className={classes.title}>
            Hello JSS-React!
        </h1>
    </div>
)

export default injectSheet(styles)(App)

glamorous

import React from 'react'
import glamorous from 'glamorous'

const Wrapper = glamorous.div({
    backgroundColor: 'black'
})

const Title = glamorous.h1({
    color: 'white'
})

const App = () => (
    <Wrapper>
        <Title> Hello JSS-React!</Title>
    </Wrapper>
)

export default App;

Radium (caveat: uses inline styles)

import React, { Component } from 'react';
import Radium from 'radium';

@Radium // decorator
class App extends Component {
	render() {

        const styles = {
            wrapper: {
                background: 'blue',
            }
            title: {
                color: 'white'
            }
        };

		return (
            <div style={styles.wrapper}>
                <h1 style={styles.title}>Hello Radium!</h1>
            </div>
		);
	}
}

export default Radium(App);

Lưu ý: Radium sử dụng decorators!

Aphrodite

import React, { Component } from 'react';
import { StyleSheet, css } from 'aphrodite';

const styles = StyleSheet.create({
    wrapper: {
        backgroundColor: 'red'
    },
    title: {
        backgroundColor: 'blue'
    }
});

class App extends Component {
    render() {
        return (
            <div className={css(styles.wrapper)}>
                <h1 className={css(styles.title)}>Hello Aphrodite!<h1>
            </div>;
        )
    }
}

Stylotron

import React, { Component } from 'react';
import { styled } from 'styletron-react';

const Wrapper = styled('div', {
    backgroundColor: 'black'
})

const Title = styled('h1', {
    color: 'white'
})

class App extends Component {
    render() {
        return (
            <Wrapper>
                <Title>Hello Styletron!<Titleh1>
            </Wrapper>;
        )
    }
}

Có nhiều ví dụ rất đơn giản để thể hiện core functionality. Tất cả thư viện đều có nhiều hơn các tính năng đi kèm – ví dụ như: themingdynamic propsserver side rendering

Chi tiết về các tính năng CSS-in-JS xem tại đây

Danh sách đầy đủ những thư viện hay của CSS-in-JS tại đây

Nguồn: TopDev via hackernoon.com

Những gì tôi học được từ 1000 code reviews

Dưới đây là 3 gợi ý code review (kèm thêm 1 cái bonus) mà tôi tổng hợp được.

Gợi ý 1: Ném (throw) 1 exception khi gặp vấn đề

Pattern mà tôi hay thấy chính là:

List<String> getSearchResults(...) {
  try {
    List<String> results = // make REST call to search service
    return results;
  } catch (RemoteInvocationException e) {
    return Collections.emptyList();
  }
}

Pattern này thực sự không hiệu quả với 1 mobile app mà tôi đã từng làm việc. Search backend tôi đang sử dụng bắt đầu throw exceptions. Tuy nhiên, API server của ứng dụng đã có vài đoạn code tương tự như ở trên. Vì vậy, từ khía cạnh của ứng dụng thì nó đã nhận được 200 response thành công và hiển thị 1 danh sách trống cho mọi truy vấn search.

Nếu thay cho việc API đã throw 1 exception, thì các hệ thống monitor của chúng ta sẽ bắt exception này ngay lập tức và fix nó.

Có nhiều lúc bạn sẽ chỉ muốn trả lại 1 object rỗng sau khi đã bắt được 1 exception. Các ví dụ về các objects trống trong Java là Optional.empty(), null, và danh sách trống. Nơi thường xuyên xảy ra chuyện này chính là URL parsing. Thay vì trả lại null nếu URL không thể parse từ String, hãy tự hỏi mình: “Tại sao URL này lại sai form? Đây có phải là vấn đề data mà chúng ta nên sửa upstream?”

Các objects rỗng không phải là công cụ phù hợp cho việc này. Nếu có ngoại lệ, bạn nên throw 1 exception.

Gợi ý 2: Sử dụng type chuyên biệt nhất có thể

Gợi ý này về căn bản sẽ đối lập stringly typed programming.

Tôi thường xuyên thấy những đoạn code như các ví dụ sau:

void doOperation(String opType, Data data); 
// where opType is "insert", "append", or "delete", this should have clearly been an enum

String fetchWebsite(String url);
// where url is "https://google.com", this should have been an URN

String parseId(Input input);
// the return type is String but ids are actually Longs like "6345789"

Sử dụng type chuyên biệt nhất có thể giúp bạn tránh được rất nhiều bug và về cơ bản là lý do để chọn ngôn ngữ strongly typed như Java ngay từ đầu.

Vì vậy, câu hỏi ở đây là: làm thế nào để các programmer có ý tưởng tốt cuối cùng lại viết ra những đoạn code stringly typed tệ như vậy? Đáp án là vì thế giới bên ngoài không phải strongly typed. Strings có thể đến từ rất nhiều nơi khác nhau như:

  • query và path parameters trong urls
  • JSON
  • databases không hỗ trợ enums
  • các thư viện được viết ra tệ

Trong những trường hợp này, bạn nên sử dụng chiến lược sau: giữ string parsing và quá trình serialization bên rìa program của bạn. Ví dụ:

// Step 1: Take a query param representing a company name / member id pair and parse it
// example: context=Pair(linkedin,456)
Pair<String, Long> companyMember = parseQueryParam("context");
// this should throw an exception if malformed

// Step 2: Do all the stuff in your application
// MOST if not all of your code should live in this area

// Step 3: Convert the parameter back into a String at the very end if necessary
String redirectLink = serializeQueryParam("context");

Một số lợi ích mà bạn có thể thấy là: Data bị sai form sẽ được phát hiện ngay lập tức; ứng dụng sẽ nhanh chóng không hoạt động nếu có vấn đề. Bạn cũng không phải tiếp tục “bắt” parsing exceptions toàn bộ ứng dụng khi data đã được xác thực 1 lần. Ngoài ra, strong stypes tạo cho nhiều method signatures descriptive hơn; bạn không cần phải viết nhiều javadocs trong mỗi method.

Gợi ý 3: Sử dụng Optionals thay vì các nulls

Một trong những tính năng tốt nhất của Java 8 là class Optional đại diện cho 1 thực thể có thể tồn tại hoặc không tồn tại 1 cách hợp lý.

Câu hỏi nhỏ đặt ra là: Exception duy nhất để có chữ viết tắt của nó là gì? Câu trả lời: 1 NPE hoặc Null Pointer Exception. Đây chính là exception thông dụng nhất trong Java và đã được nhắc đến như 1 lỗi giá trị tỷ đô

Optional cho phép bạn remove hoàn toàn NPEs ra khỏi program của bạn. Tuy nhiên, cần phải sử dụng Optional đúng cách và đây là vài lời khuyên cho bạn:

  • Bạn không nên chỉ call .get() bất cứ khi nào bạn có Optional để dùng, thay vào đó hãy suy nghĩ cẩn thận về trường hợp Optional không hiện diện và đưa ra 1 giá trị mặc định phù hợp
  • Nếu bạn chưa có giá trị mặc định phù hợp thì các methods như .map() và .flatMap() sẽ giúp bạn trì hoãn quyết định này
  • Nếu 1 thư viện external library trả về null để biểu thị 1 case rỗng thì ngay lập tức sẽ wrap giá trị bằng Optional.ofNullable(). nulls có khuynh hướng “thổi phồng” trong các programs nên tốt nhất là ngăn chúng ngay từ source
  • Sử dụng Optional trong type return của các methods. Lúc này, bạn sẽ không cần phải đọc javadoc để xác định liệu giá trị không hiện diện được không

Gợi ý kèm theo: “Gỡ bỏ” các methods bất cứ khi nào có thể

Bạn nên tránh các methods như thế này:

// AVOID:
CompletableFuture<T> method(CompletableFuture<S> param);
// PREFER: 
T method(S param);

// AVOID:
List<T> method(List<S> param);
// PREFER:
T method(S param);

// AVOID: 
T method(A param1, B param2, Optional<C> param3);
// PREFER:
T method(A param1, B param2, C param3);
T method(A param1, B param2);
// This method is clearly doing two things, it should be two methods
// The same is true for boolean parameters

Điểm chung của các methods này là gì? Chúng đang sử dụng container objects như Optional, List, hoặc Task trong vai trò là các chỉ số method. Thậm chí còn tệ hơn khi return type cùng loại với container (như 1 param methods sẽ lấy 1 Optional và trả lại 1 Optional).

Tại sao
1) Promise<A> method(Promise<B> param) ít linh hoạt hơn việc chỉ có 2) A method(B param).

Nếu bạn có Promise<B> thì có thể sử dụng 1) hoặc sử dụng 2) bằng cách “gỡ bỏ” hàm đó bằng .map. (như: promise.map(method)).

Tuy nhiên, nếu bạn chỉ có B thì có thể dùng 2) mà không thể dùng 1), điều này giúp cho 2) trở thành lựa chọn linh hoạt hơn.

Nếu thích gọi quá trình này là “unlifting” – “gỡ bỏ” vì nó đối lặp với functional utility method thông dụng là “lift”. Việc áp dụng các rewrites này sẽ giúp methods linh hoạt hơn và dễ sử dụng hơn cho các callers.

Nguồn: TopDev via hackernoon.com

Expressjs là gì? Framework mạnh mẽ Nodejs Express

Expressjs là gì

Expressjs là gì? Nếu đã từng vào nhà hàng kiểu ngồi (sit-down restaurant), bạn sẽ hiểu được những kiến thức cơ bản về Express. Nhưng nếu chỉ mới build backend Node.js lần đầu thì… bạn sẽ gặp khá nhiều khó khăn.

Yes, nếu đã làm việc với Javascript bạn sẽ học Node nhanh hơn. Nhưng thách thức đối mặt khi xây dựng backend hoàn toàn khác với những thách thức khi sử dụng Javascript ở frontend.

Khi học Node, tôi đã chọn 1 cách học khó nhằn là nghiên cứu eBooks, các tài liệu hướng dẫn, videos.. cứ như vậy cho đến khi thực sự hiểu tại sao mình lại làm những gì mình đang làm.

  Tự học Node.js thì bắt đầu từ đâu? Học Node.js có khó không?

Nhưng có 1 cách dễ hiểu hơn, là sử dụng câu chuyện so sánh liên quan đến nhà hàng kiểu ngồi để giải thích 4 phần quan trọng nhất trong app Express đầu tiên của bạn. Express.js là 1 framework dùng để sắp xếp code nổi tiếng, thường được các bạn mới bắt đầu code sử dụng.

Bài viết “Expressjs là gì?”sẽ tập trung vào 4 phần chính sau:

  1. Require statements trong Expressjs là gì?
  2. Middleware
  3. Routing trong Expressjs là gì?
  4. App.listen()/ Starting the server

Trong phép so sánh này, bạn sẽ là chủ nhà hàng đang muốn tuyển Manager chung – người tạo nên tất cả quy trình và quản lý nhà hàng 1 cách trơn tru nhất, đem lại cho khách hàng những trải nghiệm vui vẻ, hạnh phúc. .

Tổng quan bài viết Expressjs là gì như sau:

tuyển dụng it

Định nghĩa về Expressjs là gì?

Expressjs là một framework được xây dựng trên nền tảng của Nodejs. Nó cung cấp các tính năng mạnh mẽ để phát triển web hoặc mobile. Expressjs hỗ trợ các method HTTP và midleware tạo ra API vô cùng mạnh mẽ và dễ sử dụng.

Express is a node js web application framework

tuyển dụng it

Tổng hợp một số chức năng chính của Expressjs như sau:

  • Thiết lập các lớp trung gian để trả về các HTTP request.
  • Define router cho phép sử dụng với các hành động khác nhau dựa trên phương thức HTTP và URL.
  • Cho phép trả về các trang HTML dựa vào các tham số.

Dưới đây là một ví dụng để bạn sẽ hiểu được chức năng của mỗi phần trong 1 ứng dụng Express cơ bản.

Bước 1: thuê Manager (require statements)

  bodyParser() trong Express.js

Nếu muốn nhà hàng hoạt động hiệu quả, bạn sẽ cần 1 người giúp nhân viên làm việc hiệu quả ở mức tối đa. Express sẽ là “nhân vật” Manager như thế.

Cũng giống như bất kì package NPM nào khác, bạn cần phải npm install module express, sau đó sử dụng lệnh require để load module.

topdev

Khác với nhiều NPM packages khác, bạn cũng cần viết line sau:

const app = express();

Phải viết line này vì cần có 1 biến số để giữ Express application mới của mình. Express không phải là phần mặc định của Node.

Bước 2: đưa ra các quyết định quản lý ở nhà hàng (middleware)

Theo bạn, đâu là hoạt động thường diễn ra ở mọi nhà hàng? Đó sẽ là 3 hoạt động sau:

  1. Mời khách đến ghế ngồi
  2. Lấy order
  3. Tính tiền

Với mỗi hoạt động như vậy, sẽ có 1 loạt thứ phải chạy trước khi thực hiện được hoạt động đó. Ví dụ, trước khi mời khách vào ngồi, bạn cần biết:

  1. Họ có đang mặc sơ mi và mang giày không? Nếu không thì sẽ không được ngồi.
  2. Nếu họ muốn ngồi ở quán bar thì đã đủ 21 tuổi chưa? (nếu bạn đang ở Mỹ)

Tương tự với code, bạn sẽ cần phải xác nhận rằng các requests đảm bảo 1 chuẩn mực nào đó trước khi tiếp tục. Ví dụ, nếu ai đó cố gắng đăng nhập vào site thì:

  3 bài học xương máu mà mỗi Product Manager đều phải trải qua.
  1. Họ có tài khoản chưa?
  2. Họ nhập password đúng chưa?

Đây là lý do concept middleware đã xuất hiện. Các hàm Middleware cho phép chúng ta thực hiện hành động trước request bất kì và modify nó trước khi gửi lại response.

Expressjs là gì

Trong nhà hàng của bạn, cần hàng loạt các nguyên tắc để đưa ra quyết định xem liệu bạn có nên mời khách vào ghế hay không. Nguyên tắc ở đây là: họ có mang áo sơ mi & giày không?

Expressjs là gì

Đầu tiên, hãy bắt đầu với app.use(). Đây là những rules đơn giản cần phải áp dụng để thực hiện các bước tiếp theo. Những rule này không phải GET, POST, PUT hay DELETE.

Ở line 4, có 1 hàm ẩn danh với các thông số req, res và next. Xét trong code block này, bạn chỉ đang kiểm tra request (req) để xem liệu có áo sơ mi & giày hay không.

Cuối cùng, bạn cũng cần phải sử dụng hàm next() vì ở đây bạn chỉ đang xác nhận trang phục. Các bước tiếp theo, bạn sẽ cho phép khách được thực sự vào bàn ăn.

Ở line 5 & 6, bạn sẽ kiểm tra liệu các khách hàng đó có mặc áo và mang giày không.

Và ở line 7–9, bạn chỉ tiếp tục nếu các vị khách có cả 2 là mặc áo & mang giày.

Code block ở trên bị thiếu 1 thứ quan trọng là path. Đây là string riêng đi chung với request. Và bởi vì thiếu path, nó sẽ chạy theo mỗi single request.

  Con đường trở thành Product Manager từ lập trình viên tại Amazon

Bạn có thể tưởng tượng được không? Khi khách vào nhà hàng, gọi món, tính tiền, nhân viên sẽ phải nhìn họ trên dưới để đảm bảo là họ có mặc đồ! Nghe thật vô lý & trái với nguyên tắc kinh doanh.

Expressjs là gì

Vì vậy, chúng ta đã thay đổi line 4 trong ví dụ ở trên. Bây giờ, chúng ta chỉ chạy đoạn code này khi 1 user truy vấn cùng route ‘/table’.

Chi tiết có thể xem hình bên dưới:

Expressjs là gì

Tuyển dụng Nodejs TPHCM lương cao 

Bước 3: thực hiện các routines (routing)

Tiếp tục với ví dụ về việc mời vào chỗ ngồi. Cho đến lúc này, chúng ta chỉ biết được cách để xác thực liệu ai đó có nên được ngồi vào ghế hay không. Nhưng tôi thực sự không biết cách nào để đưa họ vào bàn và mời họ ngồi.

Chính lúc này, routes đã xuất hiện. Routes cho phép chúng ta soạn thảo (script) các hành động dựa trên path. Các options sẽ là GET, POST, PUT & DELETE, nhưng hiện tại chúng ta sẽ tập trung vào GET và POST.

Trong bối cảnh nhà hàng, chúng ta cần phải tạo 1 request GET để chọn 1 bàn ăn cụ thể và mời khách ngồi. GETs không modify hay thêm vào database của bạn. Chúng chỉ lấy thông tin dựa trên các thông số cụ thể.

Trong trường hợp này, bạn sẽ cần tạo 1 quy trình để sắp xếp chỗ ngồi cho 1 buổi tiệc với 2 khách. Số 2 xuất phát từ request của khách hàng.

Expressjs là gì

Đúng vậy, đây chỉ là hành động gửi đi 1 tin nhắn vào lúc cuối. Nó vẫn chưa thực sự tìm được 1 bàn cụ thể để mời khách ngồi. Tôi sẽ cần phải tìm 1 array cho 1 bàn ăn còn trống và xử lý tình huống bên lề – tình huống nằm ngoài tầm giải quyết của tutorial này.

Ở line 12, chúng ta define quy trình này để tìm kiếm bàn ăn khi 1 vị khách requests cùng route ‘/table’. Cũng giống như ví dụ về middleware ở trên, chúng ta có sẵn các thông số request & response, có 1 parameter mà trong ví dụ này là hai.

Trên thực tế, mọi thứ đằng sau function declaration ở line 12 về mặt kỹ thuật là middleware vì nó modify user request. Bạn sẽ thấy điều đó trong biểu đồ ở dưới.

Ở line 13, chúng ta tiếp cận 1 số lượng người trong bữa tiệc từ các parameters của request object. Nó không được declare ở bất kì đâu vì request đến từ user và chúng ta không có dòng code frontend nào. Vì vậy nếu đây là 1 ứng dụng thực sự thì request sẽ trông như thế này:

req = {
  params: {
    amount: 2;
  }
}

ở line 13, biến party tiếp cận property của object params trong request ở trên.

Cuối cùng ở line 14, chúng ta gửi 1 response trở lại với khách hàng: chúng ta đang tìm kiếm bàn ăn có kích cỡ vừa phải.

Đây là biểu đồ tóm gọn lại mọi thứ:

Expressjs là gì

Bước 3.5: khai thác tối đa nhà hàng (router)

Bây giờ, bạn có thể truy dấu vết của toàn bộ đường đi từ request đến response. Nhưng khi app của bạn tăng về kích cỡ, bạn sẽ không muốn code những nguyên tắc này độc lập cho mỗi route. Bạn sẽ nhận ra 1 vài routes chia sẻ cùng các rules, vì vậy cần phải tìm cách để ứng dụng 1 set các rules vào nhiều routes.

Nói riêng việc mời khách vào chỗ ngồi, bạn có thể mời khách vào quầy bar hoặc vào bàn ăn. Chúng đều có những nguyên tắc chung như áo sơ mi + giày, nhưng muốn ngồi ở quầy bar thì các thành viên của bữa tiệc phải đủ 21 tuổi.

Và, xét trên câu chuyện phục vụ khách hàng, bạn sẽ cần phải dùng đến 1 quy trình khác đi 1 chút như phục vụ món khai vị, món chính và yến tiệc. Tuy nhiên, 3 routes đó đều có nhiều điểm giống nhau.

Lúc này, router sẽ giúp bạn bằng cách nhóm các routes để từ đây bạn có thể tạo các nguyên tắc chung.

Expressjs là gì

Chúng ta cần phải tạo middleware để giải quyết hết mỗi trường hợp này. Bạn sẽ chỉ cần xử lý các trường hợp mời chỗ ngồi vì nó sẽ overwrite đoạn code ở trên.

Trích dẫn toàn bộ code ở trên:

Expressjs là gì

Tôi sẽ giải thích riêng biệt mỗi phần.

Ở line 4, chúng ta declare router.

Ở lines 6 & 14, chúng ta hiện có seatingRouter.use() thay thế cho app.use() để chỉ ra rằng middleware này chỉ liên quan đến các routes seatingRouter.

Cuối cùng, ở line 21, chúng ta thêm middleware, cho thấy rằng mỗi seatingRouter route bắt đầu với ‘/seating’. Vì vậy, nếu ai đó yêu cầu 1 ghế ngồi ở quầy bar, toàn bộ path sẽ là ‘/seating/bar.’ Nghe có vẻ lệch quy trình nhưng bạn có thể đang mong là path sẽ được define khi bạn tạo router ở line 4.

Bình thường thôi, hãy xem form biểu đồ sau:

tuyển dụng it

Và, khi thêm 1 route GET, nó sẽ ở trên statement cuối – nơi bạn chỉ định các routes đến router.

Expressjs là gì

Bước 4: bắt đầu kinh doanh (ports)

Bạn đã thuê manager, xác định những gì phải làm trước khi chấp nhận customer requests, và xác định những gì phải làm với các customer request cụ thể khi chúng xuất hiện. Bây giờ, chúng ta chỉ cần xác định chính xác địa chỉ cho địa điểm diễn ra tất cả các bước này.

Server của bạn có các ports, tương tự như địa chỉ của chính nhà hàng. Vì server có thể xử lý nhiều loại nhà hàng (hoặc các script server-side) cùng 1 lúc, nên bạn cần phải cho server biết nơi mà mỗi script nên chạy.

Expressjs là gì

Trong ví dụ ở trên, port là 3000 và được định vị trong máy tính của bạn. Vì vậy, nếu bạn gõ:

https://localhost:3000/

vào browser của mình, và bạn đang chạy app Node, server sẽ biết cách chạy script cụ thể. Trong trường hợp này, ngay khi nhập URL, bạn sẽ nhập message vào console và có thể sử dụng các routes bất kì. Nếu bản thân nhà hàng là toàn bộ ứng dụng của bạn thì hiện tại nó đã bắt đầu kinh doanh ở địa chỉ 3000.

Expressjs là gì

Trở thành người dùng Stack Overflow thông minh chỉ với 5 bước đơn giản

Các software developers thực lòng sẽ khó sống nổi nếu thiếu Stack Overflow vì Stack Overflow tiết kiệm thời gian rất nhiều, bạn sẽ không phải nhìn chằm chằm vào màn hình & cố phát minh ra cái gì đó.

Content vẫn là điều tạo nên giá trị của Stack Overflow khi mà mọi thứ bạn có thể nghĩ tới đều đã có trên Stack Overflow. Giả như bạn gặp vấn đề nào đó không thể 1 mình giải quyết, bạn sẽ Google & link đầu tiên chắc chắn là câu hỏi đến từ Stack Overflow với đoạn code mà bạn đang tìm.

Nhưng không có gì là miễn phí. Mỗi thông tin hữu ích dù là nhỏ cũng là kết quả công sức của ai đó. Họ đã dành thời gian để nghiên cứu vấn đề và viết lại những kết quả tìm thấy được, cuối cùng sẽ có nhiều người hưởng lợi từ kết quả đó hơn. Đó chính là bạn và tôi.

Có 1 nghiên cứu tâm lý xung quanh trường hợp con người khi là 1 phần của 1 nhóm tổ chức lớn. Khi gặp phải vấn đề, chúng ta sẽ vô thức mong đợi là có ai đó khác “sẽ xử lý vấn đề này”. Chúng ta đều tích cực hoàn thành các nhiệm vụ cá nhân, nhưng nếu vấn đề không ảnh hưởng trực tiếp đến mình, chúng ta sẽ chuyển giao nhiệm vụ đó cho “ai đó khác”.

Không có luật lệ gì cụ thể trên Stack Overflow, nhưng chúng ta cần phải active trên đó để mang lại nhiều giá trị cho tất cả mọi người. Dưới đây là 5 practices để bạn trở thành người dùng Stack Overflow thông minh hơn.

1. Upvote

Nếu bạn chắc câu trả lời đúng thì hãy upvote, dù đó có thể không phải câu trả lời cho câu hỏi của bạn hoặc bạn không cần nó. Upvote sẽ giúp câu trả lời kia được công nhận là đúng và thu hút nhiều sự chú ý hơn.

Không bao giờ vote (up hoặc down) nếu bạn chưa chắc chắn!

Nhìn theo góc độ khác, bạn là người post câu trả lời, tức là đã dành kha khá thời gian cho nó, tức là bạn là người sẵn lòng giúp đỡ, rộng lượng… nhưng chẳng ai phản hồi gì? Bạn chắc chắn sẽ cảm thấy xấu hổ.

Nói chung chúng ta phải thể hiện sự trân trọng đóng góp của mỗi cá nhân bằng cách upvote.

2. Viết comments

Thỉnh thoảng sẽ có người vô ý post câu trả lời sai hoặc vài câu ngớ ngẩn. Có thể là họ muốn hỏi gì đó nhưng không có ai để hỏi vì bị vote down mà số votes lại bị ẩn. Điều này xem ra không công bằng & sẽ khiến những người này cảm thấy không hài lòng.

Chúng ta không nên bỏ qua thông tin sai lệch này, thay vào đó nên viết comment để trình bày ý kiến của mình. Nhiều khả năng những người đó sẽ sửa câu trả lời hoặc xóa đi.

3. Thường xuyên đọc top các câu hỏi

Stack Overflow cũng giống như newsfeed trên Facebook, nhưng dành cho những người mọt sách. Hãy xem qua các câu hỏi đang nằm trên top, mở những câu có gắn các tags mà bạn đang quan tâm, dù cho bạn không có ý định trả lời chúng đi nữa.

Hãy cư xử như 1 chuyên gia & bạn sẽ cải thiện được đáng kể khả năng của mình. Hãy học hỏi những khó khăn mà đồng nghiệp đang gặp phải, cách họ vượt qua những vấn đề đó và cách lập luận của họ.

Đôi khi những câu hỏi tầm thường vẫn được trả lời rất “sáng” nước và bạn sẽ không muốn bỏ qua chúng đâu!

4. Đặt câu hỏi – Chẳng có gì phải xấu hổ!

Dù bạn đặt 1 câu hỏi cực kì ngốc thì điều tệ nhất có thể xảy ra là bạn sẽ bị nhận vote down hoặc vài comments tiêu cực. Chẳng có ai hạ thấp điểm danh tiếng của bạn nếu bạn xóa câu hỏi đó.

Có thêm 1 khả năng nữa là sẽ không ai chú ý đến câu hỏi đó vì nó quá rộng hoặc quá tiểu tiết. Nói chung chẳng có vấn đề gì nên là bạn cứ xóa đi sau vài ngày nếu cảm thấy không vui.

Số lượng ngôn ngữ lập trình & công cụ lập trình đều có giới hạn nhất định nên vẫn có cơ may là bạn không phải là người duy nhất gặp phải vấn đề hiện tại.

Bằng cách đưa ra 1 câu hỏi, bạn sẽ bắt đầu hiểu vấn đề tốt hơn. Hầu hết mọi vấn đề trông có vẻ to tát vào lúc đầu nhưng sẽ nhanh chóng tan biến khi chúng ta chia nhỏ vấn đề. Bạn thậm chí còn có thể có được câu trả lời trước khi publish câu hỏi.

Cùng lúc đó, bạn nên ghi nhớ là những users khác sẽ trân trọng câu hỏi của bạn nhiều hơn nếu bạn làm research trước khi đặt câu hỏi. Chúng ta đều thích những câu hỏi độc đáo, nhiều thách thức và đều rất bực mình với các câu hỏi lặp đi lặp lại.

5. Trả lời!

Khác với 4 yếu tố trên, việc trả lời sẽ ngốn của bạn kha khá thời gian. Đây là điều mà mọi “công dân” tốt phải làm, vì nó mang lại lợi ích cho cộng đồng và cho chính công dân đó.

Bạn nên hiểu rằng: không có câu trả lời – thì không có Stack Overflow. Không ai vào trang web nếu không có câu trả lời nào. Quá rõ ràng là cộng đồng cần câu trả lời, nhưng tại sao mọi người nhất định phải trả lời?

Đầu tiên, bạn chắc chắn sẽ rất vui trong vai trò 1 chuyên gia hay hỗ trợ người khác. Thêm nữa, bạn sẽ nhận được vote up, hiển thị bên cạnh tên & avatar giúp danh tiếng ngày càng đi lên.

Cuối cùng, trả lời chắc chắn giúp bạn học thêm thứ gì đó mới. Bạn sẽ hiếm khi biết ngay được câu trả lời. Thay vào đó phải đào sâu vào câu hỏi, tạo playground project, đọc documentation và viết ra câu trả lời. Khi câu trả lời được post lên, mọi người sẽ nghĩ là bạn đã biết câu trả lời từ trước đó. Không phải rất cool ngầu không nào?

Tham khảo profile của tôi trên Stack Overflow.

Nguồn: TopDev via medium.freecodecamp.org

Xem ngay những tin đăng tuyển lập trình viên tại Hà Nội trên TopDev

UX Design là gì? Làm sao để trở thành UX designer?

Làm sao để trở thành UX/UI designer

UX là gì – Gần đây có nhiều post tuyển dụng UX design lạc đề mà mình dám chắc 90% người post lên không hiểu nội dung viết cái gì. Nhưng mà tuyển dụng nên mình kệ vì mấy bạn HR chẳng làm chuyên môn và việc spam các kênh là nghề của các bạn.

Rồi cho đến khi mọc lên một vài trung tâm dạy UX/UI design với giáo trình đào tạo lệch lạc thì mình thấy vấn đề nghiêm trọng hơn. Quảng cáo lúc nào cũng hay ho, dùng nhiều buzzwords là người học ảo tưởng về cái họ nhận được rồi lại đem những thứ đó để chinh chiến thì nhiều thứ tai hại vô cùng.

Thế nên mình quyết định viết cái post giải ngố này để mọi người có cái nhìn đầy đủ hơn và đánh giá lại mình đang ở đâu và cần bổ sung cái gì.

UX Design là gì?

UX Design (User Experience Design) là quá trình thiết kế sản phẩm nhằm tạo ra trải nghiệm người dùng (user experience) thân thiện và tối ưu. Mục tiêu của UX Design là làm cho người dùng tương tác dễ dàng nhất có thể với sản phẩm của mình.

Điều này liên quan đến việc thiết kế toàn bộ quá trình ứng dụng và tích hợp sản phẩm, bao gồm nhiều khía cạnh của thương hiệu (branding), thiết kế (design), khả năng sử dụng (usability) và chức năng (function).

Làm sao để trở thành UX/UI designer

UX design thường đi đôi với UI design với title UX/UI designer, điều này cũng dễ hiểu vì UX bao gồm cả thiết kế UI (24% như hình minh họa trên)

Tại sao lại chọn UX Designer?

Theo một thống kê không đầy đủ do mình thực hiện về mức lương hiện tại của designer thì mặt bằng lương của UX/UI Designer nói chung cao hơn khoảng 30% so với Graphics Designer.

Thậm chí những mức lương tương đương các nước có GDP gấp vài chục lần Việt Nam cũng có luôn. Sự phát triển của phần mềm và internet giúp cho người dùng có nhiều lựa chọn phần mềm hơn. Sự cạnh tranh tạo ra sự phát triển.

Vì vậy các phần mềm ngày càng phải hấp dẫn và thân thiện hơn mới thu hút được sự chú ý của người dùng và khiến người dùng móc hầu bao chi tiền. Vì là một ngành đang lên nên sự đầu tư và nhu cầu nhân sự cũng lớn hơn so với các mảng khác của thiết kế như thiết kế nội thất (interior design), thiết kế sản phẩm công nghiệp (industrial product design), thiết kế thời trang (fashion design), thiết kế đồ họa (graphics design)…

Nguyên nhân mình nghĩ do việc đào tạo chưa đáp ứng được nhu cầu. Vì cơ hội lớn nên có không ít bạn làm graphics design cũn muốn chuyển qua làm UX/UI Designer và bắt đầu tập tành thiết kế web, thiết kế app…

Ngoài ra công việc UX Design đòi hỏi sự sáng tạo vừa phải chứ không đau đầu như graphics design. Mình rất khâm phục mấy bạn làm graphics design vì sức sáng tạo vô biên. Chưa kể chuyện còn dễ bị trùng lặp ý tưởng và triển khai ý tưởng nữa.

Tóm lại, nếu chọn UX Designer thì lý do lớn nhất mình nghĩ là nó đang vào xu hướng nên có thu nhập tốt cho những người theo đuổi.

UX Designer là làm cái gì?

>>> Xem thêm: UI UX là gì? Công việc của một UX/UI designer

Ở Việt Nam không có điều kiện làm chuyên sâu nên thường UX designer sẽ đảm nhận luôn UI như mình có đề cập lí do ở trên. Quan trọng là mô tả công việc chúng ta cần làm gì.

  1. Nghiên cứu người dùng:
    • Hiểu rõ nhu cầu, mong muốn và hành vi của người dùng thông qua các phương pháp nghiên cứu như khảo sát, phỏng vấn, và quan sát.
    • Xác định các vấn đề và cơ hội để cải thiện trải nghiệm người dùng.
  2. Thiết kế giao diện người dùng (UI Design):
    • Thiết kế bố cục và các yếu tố giao diện để đảm bảo sản phẩm dễ sử dụng và thân thiện với người dùng.
    • Đảm bảo sự nhất quán trong giao diện và trải nghiệm.
  3. Wireframing và Prototyping:
    • Tạo ra các bản vẽ khung (wireframes) để biểu diễn cấu trúc và luồng thông tin của sản phẩm.
    • Phát triển các nguyên mẫu (prototypes) để thử nghiệm và cải tiến các ý tưởng thiết kế trước khi triển khai thực tế.
  4. Kiểm thử và đánh giá:
    • Thực hiện các bài kiểm thử sử dụng (usability testing) để thu thập phản hồi từ người dùng.
    • Đánh giá và phân tích dữ liệu từ các bài kiểm thử để cải tiến thiết kế.
  5. Tương tác và điều hướng:
    • Thiết kế các yếu tố tương tác như nút bấm, menu, và điều hướng để người dùng có thể dễ dàng sử dụng sản phẩm.
    • Đảm bảo các yếu tố tương tác hoạt động mượt mà và trực quan.

Tham khảo thêm việc làm UX Designer tại Topdev mới nhất.

Học hành thành UX Designer

Ở bên trên bạn đã biết UI Designer làm cái gì rồi và cần cái gì rồi. Học thì đi đôi với hành, học bao gồm cả tư duy lẫn kĩ năng sử dụng phần mềm. Dưới đây mình sẽ “bày” một số gợi ý để bạn nhanh chóng lĩnh hội được. Tuy nhiên để hiệu quả, mình khuyên các bạn nên kiếm một người cho bạn những lời khuyên và sửa lỗi sai cho bạn đúng nghĩa (mentorship). Việc này sẽ giúp bạn đi nhanh hơn rất nhiều.

TỪ CON SỐ 0

Giả sử bạn đang là tờ giấy trắng tinh, không biết gì hết. Có hai con đường cho bạn:

Con đường thứ nhất:

Học lấy một cái nghề nuôi sống được bản thân rồi tính tiếp.

Con đường thứ hai:

Học từ những thứ cơ bản: Học lấy cái nghề nuôi sống bản thân thì bạn sẽ học công cụ đầu tiên. Bạn cần sử dụng thành thạo một công cụ tới mức quen tay và đáp ứng một công việc cụ thể.

Thành thạo tới mức đưa một file ảnh ra thì bạn có thể dùng công cụ để tái hiện lại file thiết kế. Bạn xem nhiều Dribbble, Behance rồi bắt chước lại. Thỉnh thoảng bạn cũng đưa ra một vài điều chỉnh nhỏ mà bạn thấy hợp lý.

Tiếp đó thì bạn xin vào các công ty outsource phần mềm hoặc các công ty làm theme với công việc làm UI Designer (có lẽ đa phần các bạn tự học sẽ thấy mình đâu đó trong này). Nếu đã tới đây mà bạn thấy bế tắc trong hướng phát triển tiếp thì nên cân nhắc học lại một số thứ cơ bản.

Học từ những thứ cơ bản thì các bạn nên học quan sát. Quan sát mọi thứ xung quanh, tự đặt câu hỏi tại sao nó lại như vậy, tại sao nó không như thế kia. Kế đó là học vẽ. Vẽ tay hay vẽ máy cũng được. Hãy coi đấy là công cụ để bạn diễn đạt thế giới quan của bạn.

Khi học vẽ bạn sẽ học qua một chút giải phẫu người, một chút phác thảo v.v. những cái này giúp bạn tạo một thói quen là vẽ dựa trên một số cơ sở nhất định. Kế đó bạn mới bắt đầu học thêm các công cụ thiết kế để diễn tả suy nghĩ của mình.

Xem tin tuyển dụng UI UX designer lương cao trên TopDev

Bạn có nhiều ý tưởng tuyệt vời trong đầu và thành thạo công cụ sẽ giúp truyền tải hết ra bên ngoài. Lúc này bạn đã có thói quen quan sát, vẽ có cơ sở, biết công cụ. Tùy hướng phát triển mà bạn có thể học thêm như cách viết sao cho hay:

  • Học thêm thiết kế cho các nền tảng khác nhau (web, mobile v.v.);
  • Học thêm các kiến thức về usability để thiết kế tối ưu sử dụng của con người hơn.

Tiếp đó thì phải hành thật nhiều. Trong quá trình làm mình gặp nhiều bạn quăng một link project lên facebook với caption “các bác nhận xét giúp em”. Mình thấy các bạn chưa thật sự nghiêm túc muốn học từ lỗi sai.

Hãy mạnh dạn liên hệ những người có kinh nghiệm và trình bày đầy đủ về cái bạn đang làm. Nếu rảnh rỗi và muốn giúp bạn, họ sẽ đưa ra những lời nhận xét xác đáng đúng trọng tâm hơn là những comment trong tình trạng thiếu thông tin và người comment không có động lực rõ ràng.

Mentor cũng phát huy tác dụng lúc này như mình nói ở ban đầu. Kế đó thì bạn có thể học sâu hơn về phần production giải pháp (lập trình kiểm thử) để tìm hiểu các khó khăn trong việc cộng tác với các producer (thường là developer hoặc người làm content) để làm việc hiệu quả hơn hoặc học sâu hơn về một mảng nhỏ.

Lúc này bạn cũng phải bắt tay tự nghiên cứu kha khá nhiều và bắt đầu có suy nghĩ về thiết kế hướng mục tiêu cụ thể thay vì thiết kế chỉ cho đẹp, phục vụ tính thẩm mỹ.

TỪ GRAPHICS DESIGNER

Là graphics designer thì bạn vốn đã quen công cụ thiết kế, vốn đã bay bổng rồi. Nếu bạn chọn con đường nhanh chóng thì chỉ cần làm vài dự án/bài tập hoặc tham gia vài lớp học công cụ/quy trình ngắn hạn là các bạn có thể chuyển đổi sang UI designer. Tuy nhiên cũng như ở phía trên, bạn sẽ sớm bị mắc kẹt vì bạn bị thiếu mất cái gốc cơ bản. Hãy cố gắng dành chút thời gian học từ những thứ cơ bản sẽ tốt hơn

Tham khảo thêm các việc làm Graphic Designer lương cao tại Topdev.

RỦI RO

Ngoài những cái đã đề cập ở trên thì cá nhân mình thấy rào cản lớn nhất là khiếu thẩm mỹ chưa tốt. Cái này muốn nâng cao thì bạn buộc phải học lại từ cơ bản, hiểu những vấn đề cốt lõi nhất và luyện tập thường xuyên. Lúc này mentor sẽ phát huy tác dụng rất nhiều. Họ sẽ cho bạn vài lời khuyên hoặc giúp bạn hiểu được những thứ cơ bản nhất để bạn không bị rối trong ma trận kiến thức.

Học hành thành UX Designer

Nếu các bạn đã đọc mô tả ở phần trên thì các bạn sẽ thấy UX Designer lại không cần tới khả năng đồ họa. Như vậy đi theo con đường này thì bạn không nhất thiết phải có khả năng nhưng công việc liên quan tới giải quyết vấn đề sáng tạo (creative problem solving) nên một chút sáng tạo sẽ giúp bạn có nhiều cơ hội phát triển hơn.

Tương tự ở trên, mình cũng khuyên các bạn cần có một người mentor để cho bạn biết bạn đang ở đâu và cần làm gì tiếp theo. Tương tự như phần UI Designer, tôi sẽ chỉ ra cho các bạn cách học từ con số 0 và chuyển đổi từ một số công việc phổ biến khác có tính chất gần giống.

TỪ CON SỐ 0

Giả định bạn là tờ giấy trắng, chưa biết gì thì mình khuyên các bạn học cơ bản trước. Viết vẽ wireframe, thậm chí bạn làm được thiết kế đồ họa không giúp bạn trở thành UX Designer giỏi đâu.

Đôi khi nó còn làm hại bạn vì bạn nghĩ vậy là đủ rồi và dừng lại việc học của mình. Học từ cơ bản bạn cũng phải học quan sát, để ý tới mọi thứ xung quanh. Có một bạn là Hieu Toop có comment trên facebook mình như sau: Tony Le Đối với em, UX ở mọi nơi trong cuộc sống, khi mà cái gì làm cho con người ko happy, khó dùng, khó cầm, khó nắm, blabla :)) là UX lởm hết. Hiện tại e nghĩ UX đơn giản lắm, còn để chuyên nghiệp thì phải theo anh xem thế nào mới nói tiếp được. Em hay lao động nhiều thứ ngoài đời nên rất chịu khó quan sát, như sửa điện, thợ hồ, bốc vác :))) trải nghiệm rất nhiều và thấy UX cực kỳ quan trọng trong cuộc sống. Nó mà làm tốt thì cuộc sống này cực kỳ dễ thở, ahehe.

Bạn là người thiết kế trải nghiệm người dùng thì trước tiên bạn phải đứng ở vai trò người dùng đã. Có chú ý quan sát mọi thứ xung quanh thì bạn mới nhạy cảm về các “vấn đề” cần giải quyết được.

Kế đó, bạn tìm cách giải quyết các vấn đề. Bạn trải nghiệm nhiều (nhiều kinh nghiệm, đi đây đi đó, tích lũy vốn sống) sẽ giúp bạn dễ dàng giải quyết vấn đề hơn. Nói chung thứ hai là bạn tích lũy thật nhiều trải nghiệm cho mình.

Kế tiếp bạn mới bắt đầu học các công cụ để giúp phác thảo giải pháp của mình. Bạn nên học vẽ phác thảo đơn giản. Không cần phải cầu kì ngồi vẽ một cô gái khỏa thân đâu, bạn chỉ cần học đủ để thể hiện hết mình gì mình muốn truyền tải thôi. Công cụ quen thuộc nhất với bạn có lẽ là bút chì, giấy, cục gôm (cục tẩy).

Mình hay dùng bảng trắng và bút dạ vì xóa nhanh hơn và diện tích thể hiện đủ lớn cho cả những người khác nhìn thấy. Các công cụ wireframe, prototype giúp bạn thể hiện cách giải quyết vấn đề như vậy Cuối cùng là bạn học các phương pháp để kiểm nghiệm cách giải quyết vấn đề của mình.

Với UX Design thì người kiểm nghiệm giải pháp luôn là người dùng vì thế bạn sẽ học cách test với user để xem giải pháp của mình phù hợp hay chưa. Phạm vi giải quyết của UX Design rất đa dạng nên bạn từ từ chọn tiếp những lĩnh vực gần nhất với công việc chuyên môn mà mình mong muốn.

Bạn có thể học sâu về môi trường thể hiện (desktop, mobile, VR…) vì mỗi môi trường có một đặc điểm khác nhau; hoặc học sâu hơn về một số lĩnh vực ảnh hưởng tới con người nói chung (ergonomics, tâm lý học, cognitive science, tương tác người – máy…); hoặc các lĩnh vực cụ thể (tài chính, y tế, thương mại, dịch vụ v.v.).

Những kiến thức này giúp cho giải pháp của bạn ổn định hơn và tránh được những lỗi có thể tránh được (avoidable mistakes). Vì UX Designer không làm riêng mà phải cộng tác với nhiều người nên bạn nên học thêm về phần production giải pháp (lập trình, sản xuất nội dung) và vận hành giải pháp để giúp cho giải pháp của bạn không chỉ phục vụ tốt người dùng mà còn có tính khả thi và đáp ứng mục tiêu kinh doanh nữa.

Tất nhiên là nếu bạn có khả năng đồ họa thì có thể học thêm UI với lộ trình cơ bản như mình nói ở phần trên. Lúc này đúng nghĩa bạn là UX/UI Designer và bạn hoàn toàn kiểm soát được “how it look của sản phẩm”

TỪ UI DESIGNER

Nếu bạn đã là UI Designer thì khả năng đồ họa của bạn cũng có ít nhiều. Nếu bạn thực sự thấy mình không có khả năng phát triển ở mảng UI Design thì việc chuyển sang UX Design là một lựa chọn.

Tuy nhiên có thể bạn sẽ thấy ở trên cái bạn tận dụng lại được chỉ là khả năng diễn tả ý tưởng thông qua công cụ thiết kế và một số hiểu biết về môi trường thể hiện (web, mobile v.v.) chứ không có một tư duy đầy đủ về việc tạo ra trải nghiệm.

Vì vậy gần như bạn phải bắt đầu lại từ con số 0 Nếu bạn tương đối có khả năng đồ họa và làm UI design tốt rồi (đã nắm vững về usability cho các môi trường thể hiện) và bạn muốn học thêm để phát triển lên UX/UI Designer thì tùy lựa chọn công việc mà bạn ưu tiên học cái gì trước.

Nếu bạn tính làm ở các Agency quảng cáo thì bạn có thể học chuyên sâu về một mảng liên quan tới con người (ví dụ tâm lý học). Kiến thức sẽ giúp bạn thành công hơn ở agency quảng cáo.

Tuy nhiên khi bạn tính làm ở các loại hình công ty khác thì sẽ phải cân nhắc lại. Nếu bạn tính làm ở các agency/công ty thiết kế và xây dựng sản phẩm hoặc các công ty sản phẩm thì bạn phải học lại từ cơ bản.

Các agency/công ty thiết kế và xây dựng sản phẩm sẽ giúp bạn học rộng hơn (biết nhiều mảng, hiểu biết cơ bản) còn các công ty sản phẩm giúp bạn học sâu hơn (hiểu một mảng, hiểu biết chuyên sâu). Trong các công ty sản phẩm thì bạn được tiếp xúc với số liệu thực tế và các phương pháp định lượng nhiều hơn.

TỪ DEVELOPER

Có lẽ developer là người có nhiều lợi thế nhất khi chuyển qua nhưng lại khó thành công nhất. Nguyên nhân một phần vì đãi ngộ của designer nói chung hiện tại thấp hơn developer nên không nhiều developer muốn chuyển qua làm designer.

Thường là những bạn không thấy mình phù hợp với công việc lập trình hoặc những người thích có sự tự do và chủ động hơn mới chuyển qua (chấp nhận việc đãi ngộ thấp hơn). Developer có lợi thế lớn về tư duy giải quyết vấn đề, đặc biệt là tư duy logic. Khả năng tìm tòi tự khám phá của developer cũng cực kì tốt (thích vọc vạch, tìm kiếm thông tin, thử sai v.v.).

Tuy nhiên nói chung các bạn developer không đủ linh hoạt và mềm dẻo để “nhận thấy vấn đề”. Nôm na là kém nhạy cảm hơn các bạn designer. Tất nhiên là nói ra để các bạn tìm cách khắc phục. Có một câu anh Điệp – CEO Vật Giá dạy cả công ty mà mình luôn tâm niệm “đặt mình vào địa vị khách hàng và đối xử trên mong đợi của họ”.

Có thể với các bạn thì chỉ nghe cho vui thôi, nhưng với những bạn developer muốn chuyển qua UX Designer thì phải luôn tâm niệm cái này thì việc chuyển đổi với hoàn thiện được. Các bạn vẫn phải học theo từ cơ bản như mình đã đề cập ở trên, tuy nhiên mình nghĩ vì tố chất khó nhất (giải quyết vấn đề) các bạn đã có nên việc học sẽ nhanh thôi.

Chia sẻ từ anh Lê Anh Quang

Xem thêm việc làm IT lương cao trên TopDev

Làm thế nào để sắp xếp Clean Architecture theo Modular Patterns trong 10 phút?

Bạn vẫn còn thắc mắc về định nghĩa của modern software architecture? Bạn đang tìm kiếm software architecture tốt nhất để áp dụng cho dự án của mình? Hy vọng bài viết này sẽ giúp bạn tìm thấy câu trả lời.

Introduction

Trong định nghĩa về software development thì architecture của dự án đóng vai trò rất quan trọng nhằm đảm bảo quá trình maintenance & reusability. Software architecture đảm bảo rằng phần mềm mà bạn xây dựng có bộ khung cơ bản. Từ đây, chúng ta có thể build bất cứ thứ gì chúng ta muốn.

Câu hỏi luôn đặt ra trong đầu tôi những ngày này làm cách nào để chúng ta kết hợp Clean Architecture & Modular pattern? Tôi đã code vài thử nghiệm và cuối cùng quyết định tổng hợp lại trong bài viết này. Bài viết sẽ dựa trên kinh nghiệm có được trong quá trình phát triển phần mềm và cách để phương pháp modular có thể áp dụng concept Clean Architecture vào quá trình phát triển phần mềm này.

Tìm việc làm Software Developer các công ty

Backgrounds

Modular patterns

Cách đây 5 năm, tôi đã từng làm trong 1 dự án lớn với nhiều thành viên tham gia và lúc đó, tôi đã sắp xếp architecture theo phương pháp modular. Chúng tôi nhận ra với modular chúng tôi có thể cắt software kiểu monolith lớn thành nhiều monoliths dọc nhỏ hơn & hỗ trợ team làm việc dễ dàng hơn vì mỗi team chỉ cần tập trung vào module mà họ đang làm. Liệu có ai còn nhớ được các đoạn code xung đột trong dự án lớn không? Liệu bạn có thể dành nửa ngày (hoặc nhiều) chỉ để merge code? Chẳng khác nào là ác mộng, phải không?

Vì vậy mà trong phương pháp modular, chúng ta cần phải đảm bảo rất các modules đủ độc lập để vẫn hoạt động được dù được viết bởi các developer đơn lẻ ở mỗi team khác nhau. Phương pháp này sẽ theo style design logic với những ưu điểm như:

  • Giúp hệ thống software có thể mở rộng được, reuse được, maintain được & tùy biến được
  • Phá stack dạng nguyên khối lớn thành hỗn hợp linh hoạt các modules cộng tác với nhau (theo style nguyên khối)
  • Giúp những người mới dễ dàng hiểu được các tính năng business & các chức năng của hệ thống (vì nó đủ nhỏ).
  • Mở ra cánh cửa để tích hợp vào kiến trúc Microservices

Clean Architecture

Clean Architecture ra đời từ năm 2012 bởi Uncle Bob và theo thời gian, Clean Architecture ngày càng đóng vai trò quan trọng trong thế giới kiến trúc phần mềm. Chúng ta có thể thấy được Android architecture đã sử dụng Clean Architecture bằng cách kết hợp với MVP pattern để xây dựng kiến trúc phần mềm cho ứng dụng Mobile. Một vài bài nghiên cứu còn đề nghị sử dụng Clean Architecture cho ứng dụng web. Đầu năm năm, Uncle Bob đã cho ra mắt quyển sách Clean Architecture: A Craftsman’s Guide to Software Structure and Design, đề cập đến các best practices khi sử dụng các nguyên lý SOLID, các pattern design & 1 vài mẹo khi deploy.

Giới thiệu sơ về clean architecture, nếu bạn đã biết thì có thể bỏ qua. Theo Clean Architecture, chúng ta cần phải đảm bảo 1 vài điểm quan trọng sau:

  • Tính độc lập của Frameworks. Architecture không phụ thuộc vào sự tồn tại của 1 vài thư viện đến từ phần mềm nặng về tính năng. Điều này cho phép chúng ta sử dụng những frameworks như các công cụ, thay vì phải nhồi nhét hệ thống của bạn vào các constraints đã bị giới hạn
  • Có thể test được. Nguyên tắc business là có thể test được dù không có UI, Database, Web Server hay bất kì element bên ngoài nào khác
  • Tính độc lập của UI. UI có thể thay đổi dễ dàng mà không thay đổi phần còn lại của hệ thống. Ví dụ, 1 Web UI có thể được thay thế bởi 1 console UI mà không thay đổi các nguyên tắc business.
  • Tính độc lập của Database. Bạn có thể hoán đổi Oracle hoặc SQL Server với Mongo, BigTable, CouchDB… Các nguyên tắc business của bạn sẽ không gắn liền với database.
  • Tính độc lập của bất kì agency ngoài nào. Trên thực tế, các nguyên tắc business sẽ không liên quan gì đến những thứ bên ngoài khác

Vậy làm thế nào để Clean Architecture hoạt động hiệu quả?

Context là vua nhưng khách hàng còn quan trọng hơn thế. Vì vậy, hãy bắt đầu với câu chuyện chính là bất kì dự án nào cũng phải phân tích & hỏi khách hàng về những gì họ muốn cho hệ thống của mình, họ cần gì để giúp hệ thống làm việc. Các khách hàng sẽ cung cấp rất nhiều use cases hoặc user stories (nếu có 1 dự án Agile). Và bước cuối cùng, chúng ta sẽ phải vẽ lại biểu đồ use case. Chẳng hạn như trường hợp blog engine domain. Chúng tôi muốn xây dựng trang blog có vài tính năng như đọc blog, thấy các posts của blog này, thêm vài comments trong giao diện public. Và chúng tôi có 1 cách để CRUD các actions trên blog, post và comments. Ngoài ra, chúng tôi cũng cần phải đăng nhập vào hệ thống trước khi có thể modify blogs, posts và comments. Dựa trên requirement của các tính năng cho ứng dụng này, chúng ta sẽ dừng lại ở giản đồ use case như bên dưới:

Câu hỏi đặt ra là làm sao để tạo architecture theo phương pháp modular? Thực sự thì nhân tố cốt lõi ở đây xuất phát từ Domain-Driven Design (theo quan điểm của tôi, Tackling Complexity in the Heart of Software Implementing Domain-Driven Design là những quyển sách mà bạn nên đọc) và trong trường hợp này, chúng tôi sử dụng pattern Bounded Context design pattern để phân tích & thiết kế business domain hiện tại. Nếu nhìn vào biểu đồ ở trên, bạn sẽ nhận ra chúng ta chỉ có 3 nhân tố chính cần quản lý là xác thực, blog & post. Tôi đã tách domain ứng dụng ra khỏi Access Control Context, Blog Context & Post Context (tôi chia nó thành 3 Bounded Contexts vì nó sẽ khác biệt so với các context khác do khác về kinh nghiệm domain, nhưng ít nhất cần phải phân loại yêu cầu business). Biểu đồ sẽ như thế này:

Giải thích 1 chút về biểu đồ trên: Access Control Context màu đỏ dùng cho các tasks về authentication (xác thực) & authorization (trao quyền). Blog Context màu xanh để quản lý blog như set up blog, phân công status, theme… Thứ 3 là Post Context để quản lý comments & tags. Như bạn có thể thấy, Post Context có mối quan hệ với các context khác. Bạn có thể tìm hiệu thêm về cách chúng tôi design Bounded Context (Root aggregate) qua loạt bài Effective Aggregate Design.

Do giới hạn của bài viết này, tôi chỉ có thể trình bày 1 đoạn code của Bounded Context và tôi muốn chọn Post Context vì có vẻ như đây là context thú vị nhất. Bạn có thể xem các phần khác trong codes ở GitHub của tối (link ở cuối bài viết này). Cuối cùng, sẽ có vài người đặt câu hỏi là vậy Clean Architecture sẽ liên quan đến phần nào? Đừng lo lắng, tôi sẽ trình bày project structure & bạn sẽ hiểu phần còn lại.

Để tôi giải thích structure ở trên. Đầu tiên, chúng ta có folder Framework trong biểu đồ, nó chứa tất cả mọi thứ liên quan đến toolkit cần cho dự án. Đừng quên chúng ta đang tránh sử dụng abstraction trong code của mình, mà sử dụng composition (Composition over inheritance trong OOP). BlogCore.Core sẽ không cần phải phụ thuộc vào bất kì framework hay thư viện nào, trong trong .NET SDK thì có (vài trường hợp chúng ta sẽ gọi là vanilla code của nó). Thêm nữa, chúng ta có 3 dự án: BlogCore.Infrastructure, BlogCore.Infrastructure.AspNetCore & BlogCore.Infrastructure.EfCore sẽ phụ thuộc vào EntityFrameworkCore, AspNetCore & các thư viện khác như Autofac, AutoMapper, FluentValidation, MediatR…

Thứ 2, folder Hosts ở giữa biểu đồ, chúng ta sử dụng để đặt các host projects ở đó. Bạn sẽ thấy chúng ta có 2 hosts: 1 host cho API (BlogCore.API) & host khác Single Page Application (BlogCore.App).

Thứ 3, folder Migrations được sử dụng để thực hiện các công việc migrating, trong trường hợp này, chúng ta migrate data cho Access Control Context, Blog Context & Post Context. Chúng ta có thể chọn cách migrate bằng cách sử dụng Entity Framework migration & đưa data cho chúng. Trái lại, bạn có thể sử dụng T-SQL scripts để thực hiện migration.

Cuối cùng, chúng ta có folder Modules chứa “trái tim” của ứng dụng. Chúng tôi đã chia thành các folder Bounded Context và giúp architecture trở nên rõ ràng hơn. Mỗi Bounded Context có 2 projects phụ như BlogCore.PostContext & BlogCore.PostContext.Core. BlogCore.PostContext.Core chỉ chứa các domain objects, contracts và interfaces thực sự phù hợp với các project references khác. Nguyên tắc chính là nếu chúng ta có module khác muốn sử dụng 1 vài classes, objects để nó sẽ tham chiếu <Module name>.Core & tham chiếu đến interface trong project này (chỉ phụ thuộc vào interface trong module khác. Việc này sẽ tạo loose-coupling cho những module đó. Chúng ta sẽ thu lại được nhiều lợi ích với phương pháp này).

Cùng xem chi tiết cấu trúc Post Bounded Context.

Theo tôi, chúng ta nên phân tích sau 1 vài đoạn code để hiểu hơn cách implement Clean Architecture với pattern Modular cho dự án này.

Chúng ta có Post.cs entity hoạt động như Root Aggregate trong Post Context như

namespace BlogCore.PostContext.Core.Domain
{
    public class Post : EntityBase
    {
        internal Post()
        {
        }

        internal Post(BlogId blogId, string title, string excerpt, string body, AuthorId authorId)
            : this(blogId, IdHelper.GenerateId(), title, excerpt, body, authorId)
        {
        }

        internal Post(BlogId blogId, Guid postId, string title, string excerpt, string body, AuthorId authorId) 
            : base(postId)
        {
            Blog = blogId;
            Title = title;
            Excerpt = excerpt;
            Slug = title.GenerateSlug();
            Body = body;
            Author = authorId;
            CreatedAt = DateTimeHelper.GenerateDateTime();
            Events.Add(new PostedCreated(postId));
        }

        public static Post CreateInstance(BlogId blogId, Guid postId, string title, string excerpt, string body, AuthorId authorId)
        {
            return new Post(blogId, postId, title, excerpt, body, authorId);
        }

        public static Post CreateInstance(BlogId blogId, string title, string excerpt, string body, AuthorId authorId)
        {
            return new Post(blogId, title, excerpt, body, authorId);
        }

        [Required]
        public string Title { get; private set; }

        [Required]
        public string Excerpt { get; private set; }

        [Required]
        public string Slug { get; private set; }

        [Required]
        public string Body { get; private set; }

        [Required]
        public BlogId Blog { get; private set; }

        public ICollection Comments { get; private set; } = new HashSet();

        public ICollection Tags { get; private set; } = new HashSet();

        [Required]
        public AuthorId Author { get; private set; }

        [Required]
        public DateTime CreatedAt { get; private set; }

        public DateTime UpdatedAt { get; private set; }

        public Post ChangeTitle(string title)
        {
            if (string.IsNullOrEmpty(title))
            {
                throw new BlogCore.Core.ValidationException("Title could not be null or empty.");
            }

            Title = title;
            Slug = title.GenerateSlug();
            return this;
        }

        public Post ChangeExcerpt(string excerpt)
        {
            if (string.IsNullOrEmpty(excerpt))
            {
                throw new BlogCore.Core.ValidationException("Excerpt could not be null or empty.");
            }

            Excerpt = excerpt;
            return this;
        }

        public Post ChangeBody(string body)
        {
            if (string.IsNullOrEmpty(body))
            {
                throw new BlogCore.Core.ValidationException("Body could not be null or empty.");
            }

            Excerpt = body;
            return this;
        }

        public bool HasComments()
        {
            return Comments?.Any() ?? false;
        }

        public Post AddComment(string body, AuthorId authorId)
        {
            Comments.Add(new Comment(body, authorId));
            return this;
        }

        public Post UpdateComment(Guid commentId, string body)
        {
            var comment = Comments.FirstOrDefault(x => x.Id == commentId);
            if (comment == null)
            {
                throw new NotFoundCommentException($"Could not find the comment with Id={commentId} for updating.");

            }
            comment.UpdateComment(body);
            return this;
        }

        public Post RemoveComment(Guid commentId)
        {
            var comment = Comments.FirstOrDefault(x => x.Id == commentId);
            if (comment == null)
            {
                throw new NotFoundCommentException($"Could not find the comment with Id={commentId} for deleting.");
                
            }
            Comments.Remove(comment);
            return this;
        }

        public bool HasTags()
        {
            return Tags?.Any() ?? false;
        }

        public Post AssignTag(string name)
        {
            var tag = Tags.FirstOrDefault(x => x.Name == name);
            if (tag == null)
            {
                Tags.Add(new Tag(IdHelper.GenerateId(), name, 1));
            }
            else
            {
                tag.IncreaseFrequency();
            }
            return this;       
        }

        public Post RemoveTag(string name)
        {
            var tag = Tags.FirstOrDefault(x => x.Name == name);
            if (tag != null)
            {
                tag.DecreaseFrequency();
                Tags.Remove(tag);
            }
            return this;    
        }
    }
}

Sau đó, chúng ta có PostGenericRepository.cs

public class BlogEfRepository : EfRepository
        where TEntity : EntityBase
{
    public BlogEfRepository(PostDbContext dbContext)
        : base(dbContext)
    {
    }
}

Chúng ta cần tạo DbContext cho PostContext.cs như

namespace BlogCore.PostContext.Infrastructure
{
    public class PostDbContext : DbContext
    {
        public PostDbContext(DbContextOptions options)
            : base(options)
        {
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            var entityTypes = new List
            {
                typeof(Post),
                typeof(Comment),
                typeof(Tag)
            };

            var valueTypes = new List
            {
                typeof(BlogId),
                typeof(AuthorId)
            };

            base.OnModelCreating(modelBuilder.RegisterTypes(entityTypes, valueTypes, "post", "post"));
        }
    }
}

Trong Clean Architecture, use case rất quan trọng và nên được design thật cẩn thận. Trong dự án của mình, tôi đã đặt tên nó là ListOutPostByBlogInteractor.cs

namespace BlogCore.PostContext.UseCases.ListOutPostByBlog
{
    public class ListOutPostByBlogInteractor 
        : IUseCaseRequestHandler&lt;ListOutPostByBlogRequest, PaginatedItem&lt;ListOutPostByBlogResponse>>
    {
        private readonly IEfRepository&lt;PostDbContext, Post> _postRepository;
        public IOptions&lt;PagingOption> _pagingOption;

        public ListOutPostByBlogInteractor(
            IEfRepository&lt;PostDbContext, Post> postRepository,
            IOptions&lt;PagingOption> pagingOption)
        {
            _postRepository = postRepository;
            _pagingOption = pagingOption;
        }

        public IObservable&lt;PaginatedItem&lt;ListOutPostByBlogResponse>> Process(ListOutPostByBlogRequest request)
        {
            var criterion = new Criterion(request.Page, _pagingOption.Value.PageSize, _pagingOption.Value);
            var includes = new Expression&lt;Func&lt;Post, object>>[] { p => p.Comments, p => p.Author, p => p.Blog, p => p.Tags };
            Expression&lt;Func&lt;Post, bool>> filterFunc = x => x.Blog.Id == request.BlogId;

            return _postRepository.ListStream(filterFunc, criterion, includes)
                .Select(y =>
                {
                    return new PaginatedItem&lt;ListOutPostByBlogResponse>(
                            y.TotalItems,
                            (int)y.TotalPages,
                            y.Items.Select(x =>
                            {
                                return new ListOutPostByBlogResponse(
                                    x.Id,
                                    x.Title,
                                    x.Excerpt,
                                    x.Slug,
                                    x.CreatedAt,
                                    new ListOutPostByBlogUserResponse(
                                            x.Author.Id.ToString(),
                                            string.Empty,
                                            string.Empty
                                        ),
                                    x.Tags.Select(
                                        tag => new ListOutPostByBlogTagResponse(
                                            tag.Id,
                                            tag.Name))
                                        .ToList()
                                );
                            }).ToList()
                        );
                });
        }
    }
}

Sau khi xử lý business case cho Post Bounded Context, chúng ta cần tổng hợp vài data liên quan đến Access Control Bounded Context và trong case này, chúng ta có thông tin Author, sử dụng interface IUserRepository để lấy thông tin chi tiết của author đó. Vì vậy, chúng ta giới thiệu class khác là ListOutPostByBlogPresenter.cs

namespace BlogCore.Api.Features.Posts.ListOutPostByBlog
{
    public class ListOutPostByBlogPresenter
    {
        private readonly IUserRepository _userRepository;

        public ListOutPostByBlogPresenter(IUserRepository userRepository)
        {
            _userRepository = userRepository;
        }

        public async Task&lt;PaginatedItem&lt;ListOutPostByBlogResponse>> Transform(IObservable&lt;PaginatedItem&lt;ListOutPostByBlogResponse>> stream)
        {
            var result = await stream.Select(x => x);

            var authors = result.Items
                .Select(x => x.Author.Id)
                .Distinct()
                .Select(y => _userRepository.GetByIdAsync(y).Result)
                .ToList();

            var items = result.Items.Select(x =>
            {
                var author = authors.FirstOrDefault(au => au.Id == x.Author.Id.ToString());
                return x.SetAuthor(author?.Id, author?.FamilyName, author?.GivenName);
            });

            return new PaginatedItem&lt;ListOutPostByBlogResponse>(
                result.TotalItems,
                (int)result.TotalPages,
                items.ToList());
        }
    }
}

Và chúng ta cần có 1 nơi để đăng kí những đối tượng dependency này. Vì vậy, Dependency Injection đã xuất hiện, và chúng ta sử dụng module Autofac trong dự án này. Ý tưởng này là module sẽ tự đăng kí tất cả dependency.

namespace BlogCore.PostContext
{
    public class PostUseCaseModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            base.Load(builder);

            builder.Register(x =>
                DbContextHelper.BuildDbContext&lt;PostDbContext>(
                    x.ResolveKeyed&lt;string>("MainDbConnectionString")))
                .SingleInstance();

            builder.RegisterType&lt;ListOutPostByBlogInteractor>()
                .AsSelf()
                .SingleInstance();

            builder.RegisterType&lt;ListOutPostByBlogPresenter>()
                .AsSelf()
                .SingleInstance();
        }
    }
}

Sau đó, chúng ta chỉ cần giới thiệu API đó cho những gì chúng ta đã làm

namespace BlogCore.PostContext
{
    [Produces("application/json")]
    [Route("public/api/blogs")]
    public class PostApiPublicController : Controller
    {
        private readonly ListOutPostByBlogInteractor _listOutPostByBlogInteractor;
        private readonly ListOutPostByBlogPresenter _listOutPostByBlogPresenter;

        public PostApiPublicController(
            ListOutPostByBlogInteractor listOutPostByBlogInteractor,
            ListOutPostByBlogPresenter listOutPostByBlogPresenter)
        {
            _listOutPostByBlogInteractor = listOutPostByBlogInteractor;
            _listOutPostByBlogPresenter = listOutPostByBlogPresenter;
        }

        [HttpGet("{blogId:guid}/posts")]
        public async Task> GetForBlog(Guid blogId, [FromQuery] int page)
        {
            var result = _listOutPostByBlogInteractor.Process(new ListOutPostByBlogRequest(blogId, page &lt;= 0 ? 1 : page));
            return await _listOutPostByBlogPresenter.Transform(result);
        }
    }
}

Tổng kết

Như vậy, tôi đã giúp bạn hiểu được cách giúp modular hoạt động hiệu quả trong Clean Architecture. Ít nhất chúng ta cũng biết được modular là gì, điểm nào thực sự quan trọng. Chúng ta cũng đã đi qua 1 vài overview về Clean Architecture và 1 vài điểm mạnh của nó. Và cuối cùng, biết cách implement bằng .NET Core 2.0

Hy vọng bạn có thể trả lời được câu hỏi đặt ra trên tiêu đề. Tuy nhiên, có những nội dung không được phân tích trong bài này chính là Data flowSynchronized giữa Bounded ContextsUnit TestingDeployment cho Clean Architecture.

Những điểm thú vị về nội dung

  • Biết cách modular patterns làm việc với Clean Architecture trong cùng stack
  • Hiểu thêm vài điểm mạnh & điểm yếu của Modular & Clean Architecture
  • Hiểu thêm về Clean Architecture trong thực tế
  • Biết cách sử dụng .NET Core 2.0 để implement Blog Domain

Source Code

Xem tại https://github.com/thangchung/blog-core

Chiến lược “Mưa dầm thấm lâu” thay đổi tư duy lập trình mà nhà quản lý nào cũng cần biết

Chiến lược

Tôi gặp anh Bình Nguyễn – CEO MobyteLab vào một buổi chiều Sài Gòn đổ mưa khá lớn, anh đón chúng tôi bằng một nụ cười thân thiện, nhiệt tình. Anh kể về câu chuyện khởi nghiệp kì lạ gắn liền với những con số 3 của MobyteLab, những trăn trở về thị trường tuyển dụng lập trình viên, và những câu chuyện thú vị khác nữa…

Câu khởi nghiệp…

Tháng 1 năm 2015, lúc đó anh Bình đang có một công việc ổn định, nhưng với máu đam mê kinh doanh, cùng với background sẵn là một “coder chính hiệu” nhận thấy tiềm năng thị trường mobile lúc đó là rất lớn, trong khi cung không đáp ứng đủ cầu, còn rất nhiều cơ hội. Nghĩ là làm, anh Bình rời bỏ công việc hiện tại để bắt đầu xây dựng công ty riêng cho mình với tên gọi là MobyteLab – chuyên gia công phần mềm Mobile cho thị trường nói tiếng Anh (Anh, Pháp, Mỹ, Canada…). Thời điểm bắt đầu công ty có 3 thành viên, và sau 3 năm MobyteLab đã có 13 thành viên.

3 năm không phải là thời gian quá dài đối với 1 doanh nghiệp, nhưng với một start-up đi lên từ con số 0, tham gia vào một lĩnh vực quá nhiều mạo hiểm như là làm outsource về mobile cho thị trường nước ngoài  (với những tiêu chuẩn quốc tế, sự cách biệt về không gian – địa lý cũng như bất đồng về ngôn ngữ,..) việc trụ vững được là cả một hành trình dài và không mấy dễ dàng.

Tuy nhiên nhìn lại chặng đường đã qua anh Bình vẫn lạc quan chia sẻ: “Thực ra lĩnh vực nào cũng có những đặc thù, những khó khăn riêng của ngành đó không riêng gì thị trường mà MobyteLab đang chọn. Nên đối với anh khó khăn là điều hết sức bình thường, luôn luôn nỗ lực hết mình thì khó khăn nào cũng sẽ vượt qua.”

Rất may mắn cho anh khi có được những khách hàng trung thành; một trong những sản phẩm đầu tiên mà bên anh hợp tác đã gắn bó với MobyteLab qua rất nhiều vòng đời sản phẩm, phiên bản cuối cùng mà bên anh làm cho khách hàng đó là version 5. Không chỉ gắn bó lâu dài mà khách hàng cũng chính là người giới thiệu khách hàng mới cho bên anh. Đó chính là niềm vui và cũng là động lực cho anh cũng như anh em ở Mobyte Lab.

Bài học về quản lý con người

Thành công cũng có, thất bại cũng không thiếu nhưng điều quan trọng còn lại sau cùng đó là những bài học. Những ngày đầu khi mới thành lập công ty, không cân đối được kế hoạch đề ra với nhân lực hiện có dẫn đến không bàn giao sản phẩm đúng hẹn cho khách hàng, điều đó ảnh hưởng không tốt đối với niềm tin của khách hàng với công ty. Mặc dù sao đó dự án cũng đã được bàn giao đúng yêu cầu của khách hàng, nhưng nó khiến anh không hài lòng vì đã chậm tiến độ.  

Tuyển it manager lương cao cho bạn

Bài học lần đó khiến anh suy nghĩ rất nhiều về bài toán nhân sự, làm cách nào để tối ưu hóa hiệu suất làm việc, giải phóng bớt sức người vào những công việc mang tính chất thủ công, lặp đi lặp lại và hạn chế những sai sót không đáng có. Sử dụng các công cụ hỗ trợ bên ngoài được xem là giải pháp. Mặc dù việc thuê các công cụ  ngoài có chi phí khá cao nhưng bù lại nó giúp giải quyết các vấn đề mà hiện tại công ty đang gặp phải: tối ưu nhân lực, giảm sai sót không đáng có, tăng hiệu suất làm việc, rút ngắn thời gian tạo ra sản phẩm…. Đến nay sau thời gian áp dụng các công cụ hỗ trợ vào quy trình làm việc anh tự tin rằng MobyteLab đã xây dựng được một quy trình tương đối chuẩn, đáp ứng được những yêu cầu ngày càng khắc khe của khách hàng.

Tuy có sự hỗ trợ của các công cụ bên ngoài, nhưng theo anh nhân tố con người vẫn là nhân tố quyết định chính làm nên chất lượng sản phẩm. MobyteLab đánh giá cao những bạn có tư duy lập trình tốt, có tinh thần trách nhiệm cao, và chịu khó học hỏi. Bên anh không ngại đầu tư cho các bạn tham gia các khóa học, mua tài liệu về các công nghệ mới, đầu tư trang thiết bị để test thử sản phẩm, hiện tại lập trình viên bên anh đều được trang bị máy Macbook và các thiết bị kiểm thử khác.

Chiến lược “mưa dầm thấm lâu” thay đổi tư duy lập trình viên outsource:

Bản thân anh Bình tâm niệm, dù làm Outsource hay làm Product  thì cũng phải để cái “tâm” vào từng sản phẩm mình làm, xem khách hàng như là những người bạn luôn luôn mang đến nhiều hơn những gì khách hàng mong đợi, có như vậy khách hàng mới cảm thấy được tôn trọng và mong muốn gắn bó với doanh nghiệp lâu dài. Tuy nhiên, không phải lập trình viên nào cũng có được suy nghĩ như vậy, đặc biệt là đối với những bạn làm trong môi trường Outsource.

Để thay đổi tư duy đó, đòi hỏi người quản lý cần kiên nhẫn và đủ niềm tin vào nhân viên của mình. Việc thay đổi dư duy không thể diễn ra trong ngày một ngày  hai qua 1 hoặc 2 dự án, đó là cả một quá trình cần có thời gian “mưu dầm thấm lâu” các bạn phải được trải nghiệm qua nhiều dự án, làm việc trực tiếp với khách hàng, giao tiếp thường xuyên với khách hàng, và quan trọng là phải giúp các bạn hiểu được ý nghĩa công việc mà các bạn đang làm, dần dần qua thời gian sẽ hình thành nên lối tư duy vì khách hàng, suy nghĩ cho khách hàng hàng.

Một điều khiến anh Bình còn trăn trở là thị trường lập trình viên hiện nay đang rất thiếu nhân lực, đẩy chi phí lên rất cao mà chất lượng không đảm bảo như trước, làm sao để giúp cải thiện “chất” của lập trình viên tương xứng với yêu cầu ngày càng cao là bài toán vẫn chưa có lời giải!

Nguồn: TopDev via Techtalk

Xem thêm các việc làm it tuyển gấp tại đây

Bạn trẻ ‘đu dây điện, ở trên mây’ khi phỏng vấn xin việc?

“99/100 em đi phỏng vấn đều chém câu “Em muốn làm việc trong một môi trường chuyên nghiệp!”

Chính vì sự nôn nóng mà nhiều bạn trẻ không tạo được ấn tượng ngay từ vòng đầu phỏng vấn, nhất là việc chỉ đưa ra điều kiện bản thân nhưng lại thiếu hiểu biết về công ty ứng tuyển.

Có hay không bạn trẻ “đu dây điện”?

Trong một bài chia sẻ trên mạng gây sốt mới đây, tác giả Thùy Vân – một chuyên viên truyền thông – thuật lại rằng “99/100 em đi phỏng vấn đều chém câu “Em muốn làm việc trong một môi trường chuyên nghiệp!”.

“Nghe thì hay, nhưng khi đi vào thực tế nó lại trở thành điều vô cùng khôi hài, nó phản ánh tính hài hước không giới hạn của các em” – Thùy Vân viết trên facebook.

Cô cho rằng “môi trường chuyên nghiệp” theo tưởng tượng của các bạn trẻ (công ty lớn, văn phòng đẹp, lương cao, thưởng đều, nhân viên ăn mặc đẹp, thơm tho, sếp hiền như bà tiên, ông bụt…), trong khi thực tế “môi trường làm việc chuyên nghiệp” – theo Thùy Vân – thì phải là có Quy trình chuyên nghiệp (nhân viên cần biết công việc cần làm bắt đầu từ đâu, kết thúc thế nào, phối hợp với ai, trong bao lâu phải hoàn thành); Chính sách minh bạch (thưởng phạt phân minh); Con người chuyên nghiệp (việc đã giao thì phải hoàn thành)…

Thùy Vân cho rằng “đi phỏng vấn, thay vì nói “em muốn làm việc trong một môi trường chuyên nghiêp”, hãy tự hỏi “mình đã chuyên nghiệp đủ với môi trường đó hay chưa”.

Bảo Minh – một quản lí truyền thông – cho rằng những quan điểm của Thùy Vân là thiếu cơ sở và không thông cảm cho giới trẻ. Bảo Minh viết: “Số bạn trẻ ảo tưởng không phải là không có nhưng số doanh nhân ảo tưởng cũng nhiều không kém. Tôi đã trải qua các công ty và ở công ty nào tôi cũng nhận thấy rằng mỗi khi tuyển người họ đều tự cho mình là môi trường chuyên nghiệp.

Với các em mới ra trường kinh nghiệm còn non và họ đòi một môi trường chuyên nghiệp thì tôi nghĩ chúng ta cũng không nên cười cợt và khinh khi. Nếu một người đi làm 5-10 năm với mức lương cao thì chả ai đòi hỏi câu đó, cứ trả đúng khả năng thì làm thôi”.

Tạo CV mới nhất chuẩn IT

Cần hiểu rõ cái gì quan trọng

Trao đổi với Tuổi Trẻ, Thùy Vân giải thích: “Thông điệp được truyền tải không phải là “bạn chưa chuyên nghiệp nên bạn không có quyền đòi hỏi môi trường chuyên nghiệp”, mà phải là bạn mong muốn làm việc trong môi trường chuyên nghiệp, nhưng khi được yêu cầu làm việc một cách chuyên nghiệp (đúng quy trình, đúng tiến độ…) thì bạn không làm”.

Thùy Vân góp ý rằng để giới trẻ không vấp phải những thiếu sót trong quá trình xin việc, cần phải: “Ứng viên ngoài kiến thức chuyên môn cần xác định thái độ nghiêm túc cho vị trí công việc mình ứng tuyển và sẽ làm việc trong tương lai. Điều này khác với “kỹ năng trả lời phỏng vấn”, bởi nó không phải việc bạn có “đối phó” được với nhà tuyển dụng hay không, mà là bạn sẽ cho nhà tuyển dụng thấy mình thực sự phù hợp và mong muốn gắn bó với vị trí tuyển dụng như thế nào”.

Chị Thanh Định – người có kinh nghiệm tuyển lựa nhân sự nhiều năng cho công ty Uniiik Saigon – cho hay: “Hầu hết những bạn trẻ, người mới ra trường đều muốn tìm một công việc ổn định. Tuy nhiên, cũng chính vì sự nôn nóng mà họ không tạo được ấn tượng ngay từ vòng đầu phỏng vấn. Nhất là việc chỉ đưa ra điều kiện bản thân nhưng lại thiếu hiểu biết về công ty ứng tuyển.

Hỏi đúng cách sẽ giúp các bạn trẻ hiểu hơn về công ty, tổ chức mình đang làm. Đây là cách để chứng tỏ ứng viên có hiểu biết, có quan tâm đến công việc, không phải là người thụ động. Ứng  viên không nên im lặng mà hãy tận dụng cơ hội để hỏi ngược lại người phỏng vấn”.

Nguồn: tuoitre.vn

8 quyết định quan trọng về React Component

React được mở nguồn năm 2013 và ngày càng phát triển mạnh mẽ. Nếu search trên web, bạn sẽ thấy rất nhiều bài viết & cách tiếp cận hay, và sau đây là 8 quyết định quan trọng mà team của bạn cần cân nhắc khi viết React components.

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

Quyết định 1: Môi trường phát triển

Trước khi viết component đầu tiên, team cần phải thống nhất về môi trường phát triển. Có rất nhiều lựa chọn để tham khảo…

https://twitter.com/housecor/status/913382440911212545

Tất nhiên bạn có thể xây dựng môi trường lập trình JS lại từ đầu. 25% các dev React chỉ làm có thế. Team hiện tại của tôi sử dụng create-react-app với các tính năng bổ sung như mock API thực tế hỗ trợ CRUD, 1 thư viện component reusable, và các cải tiến linting (chúng tôi cũng lint các file test – những files mà create-react-app bỏ qua). Tôi rất thích create-react-app, nhưng có 1 công cụ sẽ giúp bạn so sánh giữa nhiều lựa chọn hấp dẫn. Muốn render trên server? Hãy thử Gatsby hoặc Next.js. Bạn có thể cân nhắc sử dụng công cụ editor online như CodeSandbox.

Quyết định 2: Types

Bạn có thể bỏ qua types, sử dụng prop-types, sử dụng Flow, hoặc sử dụng TypeScript. Lưu ý rằng prop-types được trích xuất trong thư viện độc lập trong React 15.5, vì vậy các posts cũ hơn sẽ hiển thị những imports không còn hoạt động nữa.

Cộng đồng vẫn đang tranh cãi về topic này:

https://twitter.com/housecor/status/911673327240073216?ref_src=twsrc%5Etfw&ref_url=https%3A%2F%2Fmedium.freecodecamp.org%2Fmedia%2F071321ad7e2f3d3cfd84ca705d9f3633%3FpostId%3Dcc965db11594

Tôi thì vẫn thích prop-types hơn vì nó cung cấp đủ type safety trong React components với rất ích sai lệch. Khi sử dụng kết hợp Babel, Jest testsESLint, và prop-types, tôi hiếm khi nhận ra các vấn đề về runtime type.

Quyết định 3: createClass và ES Class

React.createClass là API gốc, nhưng trong 15.5, React.createClass lại không được duyệt. Một số người cho rằng chúng ta đã chuyển sang ES Classes quá sớm. Tuy nhiên, createClass style đã được chuyển ra khỏi React core & đẩy đến 1 single page là “React không có ES6” trong docs React. Như vậy, 1 thực tế rõ ràng là ES classes chính là tương lai mà chúng ta cần phải cân nhắc. Bạn có thể dễ dàng convert từ createClass sang ES Classes bằng react-codemod.

Quyết định 4: Class vs Functional

Bạn có thể declare các React components bằng class hoặc function. Các classes rất có ích khi bạn cần đến refs, và lifecycle methods. Có 9 lý do cần cân nhắc khi sử dụng functions. Nhưng cần lưu ý rằng các functional components có 1 vài điểm bất lợi mà bạn có thể tham khảo tại đây.

Quyết định 5: State

Bạn có thể sử dụng plain React component state. Lifting state scale rất tốt. Hoặc, bạn có thể sử dụng Redux hoặc MobX:

Tôi là fan của Redux, nhưng thường sử dụng plain React vì nó đơn giản hơn. Với công việc hiện tại, chúng tôi đã cho ra đời cả tá React apps và nhận ra Redux đều phù hợp với cả hai. Tôi thích cho ra đời nhiều ứng dụng nhỏ, độc lập hơn là 1 ứng dụng lớn duy nhất.

Nếu bạn quan tâm đến immutable state, vẫn có ít nhất 4 cách để state của bạn immutable.

Quyết định 6: Binding

Ít nhất cũng có 6 cách giúp bạn xử lý binding trong React components. Đứng về phía React, quyết định này hầu hết là vì JS hiện đại cung cấp nhiều cách để xử lý binding. Bạn có thể bind trong constructor, bind trong render, sử dụng function mũi tên trong render, sử dụng 1 class property, hoặc sử dụng decorators. Đọc thêm comments trong post này để có thêm nhiều lựa chọn nhé! Mỗi cách tiếp cận đều có ưu điểm riêng nhưng nếu bạn đang thích các tính năng thử nghiệm thì tôi khuyến khích sử dụng class properties mặc định (hay còn gọi là property initializers).

Bảng bầu chọn từ tháng 8/2016. Kể từ đó, các class properties đang ngày càng được ưa chuộng hơn & createClass lại ít được sử dụng.

Lưu ý: Rất nhiều người còn thắc mắc tại sao các arrow functions và bind trong render đều tiềm tàng nguy cơ gây ra vấn đề. Lý do thực sự? Nó khiến shouldComponentUpdate & PureComponent rất khó sử dụng.

Quyết định 7: Styling

Đây là nơi khiến cho các quyết định lựa chọn trở nên cực kì khó khăn. Có hơn 50 cách để style components gồm inline styles của React, CSS truyền thống, Sass/Less, CSS Modules, & các phương án 56 CSS-in-JS. Tôi đã khám phá được chi tiết các bước tiếp cận trong module styling của khóa học này, tóm tắt như sau:

Tại sao có quá nhiều phân mảnh trong các phương án styling của React

Team hiện tại của tôi hài lòng khi sử dụng Sass với BEM nhưng tôi cũng rất thích các styled-components.

Quyết định 8: Reusable Logic

Ban đầu React sử dụng mixins như 1 cơ chế để chia sẻ code giữa các components. Nhưng mixins đã gây ra vài vấn đề. Bạn không thể sử dụng mixins với ES class components, vì vậy nên gần đây cộng đồng tận dụng components higher-order & render props để chia sẻ code giữa các components.

Higher-order components đang trở nên thông dụng hơn nhưng tôi vẫn thích render props hơn vì dễ đọc, dễ tạo. Xem thêm bài trình bày của Michael Jackson

Và đó không phải là tất cả…

Vẫn còn nhiều quyết định cần xem xét khác

Và vì React hầu hết chỉ là JavaScript, nên bạn sẽ có danh sách dài các quyết định cần căn nhắc liên quan đến style phát triển JS như semicolonstrailing commasformatting, và event handler naming

Chọn Standard, sau đó automate quá trình enforcement

Những bước tiếp theo sẽ rất quan trọng:

1. Thảo luận những quyết định này với team và ghi lại standard của bạn

2. Đừng lãng phí thời gian tranh luận về tính mâu thuẫn trong code reviews. Thực thi các standards của bạn bằng những công cụ như ESLinteslint-plugin-react, và prettier.

3. Có cần phải restructure các React components hiện tại không? Hãy sử dụng react-codemod để automate toàn bộ quá trình này.

Nguồn: TopDev via medium.freecodecamp.com

Tham khảo thêm các việc làm React hấp dẫn tại đây

Vietnam Web Summit ở Hà Nội – Khép lại hành trình đáng nhớ, mở ra kỷ nguyên mới

Sáng ngày 08/12, sự kiện Vietnam Web Summit đã chính thức hoàn thành sứ mệnh kết nối, mang giá trị kiến thức đến cộng đồng Hà Nội. Gần 4000 Developer, Digital Marketer, đại diện các tập đoàn & doanh nghiệp Việt… đã cùng nhau đi qua hơn 50 nội dung chuyên sâu do hơn 50 diễn giả kinh nghiệm chia sẻ kết hợp cùng hàng chục gian hàng triễn lãm đa dạng với nhiều hoạt động thú vị đã thực sự tạo nên một bữa tiệc Công nghệ đáng nhớ.

Với sự tham gia của các tập đoàn AWS (Amazon Web Services), Facebook, Google, Zalo Business, Nielsen, MasterCard, Hope Ventures, Chili, mở màn toàn bộ ngày hội là những bài tham luận phát triển bức tranh chung toàn ngành, cung cấp những số liệu tổng quan, và các báo xu hướng ngành liên quan đến lĩnh vực Web, E-commerce, Payment và Digital Marketing.

Bí kíp lập trình Frontend & Backend dành cho Web developer

Như thường lệ, các bí kíp tối ưu hóa công việc lập trình dành là phần nội dung kỹ thuật được hưởng ứng nhiệt liệt tại các mùa sự kiện của Vietnam Web Summit và năm nay cũng không ngoại lệ. Trong đó, cụm từ Optimization trở thành chìa khóa đinh khiến các nhà phát triển Web trăn trở nhiều nhất. Đây cũng chính là lý do tại sao các topic sau luôn chật kín 3 khán phòng tham dự:

  • Topic React: Các vấn đề SEO, shared module & optimize code của diễn giả Phạm Thanh Tú – CTO của AgileTech.vn
  • Topic How to improve Frontend performance của diễn giả Trần Văn Thái – Frontend Developer của AI&T
  • Topic Frontend optimization của diễn giả Nguyễn Đình Khiêm – CTO của Western University
  • Topic WordPress optimization: How to survive millions of pageviews per month của diễn giả Gary Cao – CoFounder & President của Solis Lab
  • Topic Joomla – Cách tối ưu đáp ứng lượng truy cập cao của diễn giả Giang Nguyễn – Backend Developer của Bravebit
  • Topic UX Design: User Centered của diễn giả Lê Anh Quang – Product Director của Websosanh

Ứng dụng công nghệ 4.0 – Thực tiễn đầy thách thức

Cuộc Cách Mạng Công Nghệ 4.0 vẫn đang nhận được rất nhiều tranh cãi trong cộng đồng vì khả năng ứng dụng vẫn chưa đến mức rộng rãi như báo chí đưa tin. Tuy nhiên, tại Vietnam Web Summit, các chuyên gia đến từ các lĩnh vực khác nhau như Giáo dục, Y tế, Tuyển dụng… lại cho thấy những khía cạnh mới, những thách thức không dễ dàng trong kỷ nguyên 4.0 đòi hỏi những hoạch định và thay đổi có tính chiến lược.

Đó có thể là vấn đề bảo mật và an toàn thông tin được thể hiện qua các topic như Những lỗ hổng, kỹ thuật tấn công mới nhất trên nền tảng Web và cách phòng chống đến từ diễn giả Nguyễn Hữu Trung – Co-Founder & CTO của CyStack Security, Hacker in Industry 4.0 – Easy ways to attack your business đến từ diễn giả Nguyễn Ngân Bình – Testing Solution Architecture Manager của TesterVN, An toàn thông tin trong hệ thống y tế Nhật Bản đến từ diễn giả Phan Mạnh Hùng – CTO của Ominext hay câu chuyện Automation trong Tuyển dụng của diễn giả Trần Anh Tuấn – CMO của GetFly.

Đó cũng có thể là công nghệ Blockchain & những khái niệm mới mà các startup Việt, các cá nhân muốn tham gia vào thị trường tiền ảo phải nhanh chóng nắm bắt như bài chia sẻ ICO – Chiến lược đầu tư, tránh lừa đảo và ném tiền qua cửa sổ đến từ diễn giả Nguyễn Văn Vững – Founder & CEO của Adtop, Các bước để ICO một startup và chiến lược đầu tư cho các ICO đến từ diễn giả Lê Văn Trí – CoFounder & Business Director của TEKY, Blockchain & Smart Contract – Bắt đầu như thế nào và các ứng dụng đến từ diễn giả Nguyễn Sỹ Thanh Sơn – Director Of Engineering của Tomo.

Digital Marketing – Bạn sẽ không đánh rơi nhịp nào nữa!

Các topic Marketing tại Vietnam Web Summit đã không còn đóng vai trò “kép phụ” mà dần dần trở thành món ăn không thể thiếu giữa bữa tiệc buffet công nghệ sôi động.

Nổi bật nhất vẫn là màn đối thoại với những pha đối đáp xuất thần, những luận điểm “làm cho ra lẽ” giữa diễn giả Nguyễn Ngọc Long – Sáng lập Truyền Thông Trăng Đen và diễn giả Phan Dũng – Founder & COO của Big Cat Entertainment xoay quanh hiệu quả của Viral Content & KOLs trong chiến dịch Marketing.

Chưa dừng lại ở đó, các Marketer còn có dịp gặp gỡ và học hỏi nhiều kinh nghiệm làm Marketing hữu ích khác như: Google Analytics – Đọc số để hiểu số & insights của anh Jack Nguyễn – Country Manager tại Việt Nam & Thái Lan của Insider, What is real Performance Marketing? của chị Tân Trần – PR & Marketing Manager của Interspace Vietnam, Phương thức tối ưu hiệu quả quảng cáo online của chị Nguyễn Thùy Giang – Senior Digital Training Specialist của Cốc Cốc, Why landing page becomes trending in 2017/2018, Social Listening: Understand what people talk on Social Network by Data Science của anh Lê Công Thành – CEO của InfoRe R&D team…

Cuối cùng, không thể không kể đến khu vực booth sôi động với những trò chơi thử nghiệm VR độc đáo hay các showcase sản phẩm IoT ấn tượng… cùng phần Lucky Draw hấp dẫn của Chili.

Tất cả cùng hòa nhịp tạo nên 1 hành trình công nghệ đáng nhớ, khép lại bằng những cảm xúc bất ngờ vỡ òa cũng như mở ra một kỉ nguyên mới với những mối quan hệ hợp tác mới, những sức bật mới trong quá trình phát triển của mỗi cá nhân, mỗi doanh nghiệp đang làm việc trong lĩnh vực Công nghệ.

Về các hạng mục hợp tác: Mr. Lê Đặng Hiếu

Tổng quát về sự kiện: Ban Tổ Chức

Messaging App sẽ định hình lại E-commerce

Với sự đột phá trong công nghệ, đặc biệt là mảng di động, đã khiến cho cộng đồng IT trở nên vô cùng phấn khích, luôn dõi theo thông tin cập nhật từ những sự kiện về công nghệ. Tại Vietnam Web Summit, buổi đại tiệc dành riêng cho lập trình viên với các thông tin chuyên sâu về web và các lĩnh vực liên quan, Zalo đã có buổi chia sẻ về tình hình của thị trường Messaging App cũng như những ảnh hưởng của nó lên Ecommerce.

Bắt đầu bằng với màn tự giới thiệu về hãng, Zalo cho biết công ty đã cán mốc 80 triệu người dùng trong năm nay. Với hơn 800 triệu tin nhắn, 250 triệu media cũng như 1 tỷ từ được gửi từ Zalo, không có gì ngạc nhiên khi Zalo đứng đầu top 1 Việt Nam về lượng người dùng.

Qua đó có thể thấy rằng di động và các ứng dụng mobile có sức ảnh hưởng đến mức nào tới cuộc sống của chúng ta. Sẽ là không sai khi nói rằng thế kỉ 21 chính là bắt đầu của kỉ nguyên di động. Khi mà đã có tới 58% khách hàng mua sắm online thông qua smartphone.

Không dừng lại đó, ứng dụng nhắn tin còn thúc đẩy cả thị trường mobile commerce. Theo Zaol, top 4 các ứng dụng có mức độ phát triển nhanh nhất đều là message app. Không những thế, tỉ lệ tương tác cũng cao gấp nhiều lần so với các platform social khác. Zalo cho biết người Việt trung bình bỏ ra ít nhất 68 phút mỗi ngày để sử dụng app của hãng, cao gấp 10 lần so với những đối thủ khác.

Với xu thế toàn cầu hóa và IoT, người dùng sẽ cần tới một platform đa năng và đáp ứng được mọi nhu cầu đưa ra một cách nhanh chóng và tiện lợi. Đây cũng chính là mục tiêu mà các ứng dụng nhắn tin nhắm tới, trở nên đa năng – All in one. Trong đó, tính năng giao tiếp trực tiếp có mức độ hài lòng lên tới 73% và góp phần không nhỏ tới việc chi tiêu của người dùng. Theo số liệu được Zalo đưa ra, khoảng 31% người Mỹ và Anh, khi được hỏi, thừa nhận họ dễ đưa ra quyết định mua đồ sau khi chat trực tiếp thông qua ứng dụng nhắn tin.

Mặt khác, message app được đánh giá như một kênh quảng cáo chạy campaign tuyệt vời cho các doanh nghiệp Việt Nam với khả năng reach và tương tác cực cao.

Juno, thương hiệu giày thời trang nữ hàng đầu Việt Nam, nhờ vào việc hợp tác với ứng dụng nhắn tin Zalo đã đạt hiệu quả rất cao trong quảng cáo. Với hơn 3 triệu lượt tương tác, cũng như lượt quan tâm tăng đến 3 lần giúp hãng tiếp cận được số lượng khách hàng tiềm năng vô cùng lớn.

Không dừng lại đó, việc sử dụng ứng dụng nhắn tính còn giúp giải quyết điểm yếu của SMS Vốn chi phí rất cao, tính bảo mật thấp mà lại ảnh hưởng tiêu cực tới trải nghiệm của khách hàng.

Fe Credit là một ví dụ điển hình, sau khi chuyển qua sử dụng dịch vụ Zalo, đã đạt tới 50 ngàn tương tác mỗi ngày kèm với 2 triệu lượt tin nhắn chỉ trong tháng đầu tiên, giúp giảm 5% tổng chi phí

Ngoài ra, message app còn có tính năng E-membership, được dùng để chạy các chương trình khuyến mãi và tri ân khách hàng. Nhờ đó mà giúp duy trì lượng khách hàng trung thành cũng như cải thiện hình ảnh thương hiệu trong mắt người tiêu dùng.

Có thể nói, ứng dụng tin nhắn mang trong mình tiềm năng vô cùng lớn. Nó không chỉ thay đổi cách thức tiêu dùng của khách hàng mà còn định hình lại cách kinh doanh của doanh nghiệp.

Nỗi sầu công việc (Chương 2)

Những công việc nhàm chán thực chất là một phần vốn có và gần như không thể tránh khỏi trong nền kinh tế hiện đại.

Chuẩn hoá

Những nỗi sầu công việc không chỉ giới hạn ở việc bị bó buộc ở một lĩnh vực duy nhất trong suốt sự nghiệp; tệ hơn, lĩnh vực mà ta lựa chọn thực chất lại rất nhàm chán. Ta lại nghĩ rằng vai trò tẻ nhạt ấy là do lỗi của chính mình, là dấu hiệu của sự vụng về, nhưng nếu ta xét một cách vô cảm, những công việc nhàm chán thực chất là một phần vốn có và gần như không thể tránh khỏi trong nền kinh tế hiện đại.

Khi nhắc đến công việc trái ngược với nhàm chán, một công việc thú vị, ta có khuynh hướng nghĩ đến những công việc cho phép tự trị, chủ động và sáng tạo (từ này không mang ý nghĩa chỉ nghệ thuật). Trong một công việc thú vị, ta không chỉ đơn giản là làm theo lệnh, ta sẽ biết được chính xác cần chọn con đường nào để đạt được mục tiêu hoặc để tìm ra giải pháp đúng đắn cho vấn đề. Một công việc tốt được định nghĩa là công việc thừa nhận sự cá nhân hóa: con người thật của chúng ta có cơ hội được để lại dấu ấn trong công việc ta thực hiện. Ta sẽ có thể nhìn thấy được những điều tốt đẹp nhất ở tính cách của mình trong những sự vật hay dịch vụ mình tạo ra.

Có thể đọc những bài viết về bản chất công việc ra đời ở châu Âu và Mỹ vào thế kỷ 19 để hiểu vì sao cá nhân hóa lại biến mất khỏi thị trường lao động (dù cho tiền lương gia tăng). Nhà phê bình nghệ thuật và cải cách xã hội John Ruskin đưa ra ý kiến cho rằng ngành công nghiệp xây dựng Trung Cổ có dấu ấn cá nhân hóa rất lớn, thể hiện rõ ở cách các thợ thủ công điêu khắc những bức tượng gargoyle – những gương mặt thú hoặc người kỳ quặc – với hình thù độc đáo trên mái nhà của các nhà thờ. Những người thợ có lẽ đã vạch ra một thiết kế tổng thể cố định và công việc của họ không phải lúc nào cũng dễ dàng, nhưng các gargoyle biểu trưng cho sự tự do cơ bản trong việc để lại dấu ấn trong công việc. Riskin cũng buồn rầu cho rằng những cải tiển nhà ở của thời đại công nghiệp không có chỗ cho sự tự do như vậy, cũng không có chỗ cho chủ nghĩa cá nhân nảy nở trong lực lượng lao động.

Môn đồ tận tụy nhất của Ruskin, nhà thơ và nhà thiết kế William Morris mở rộng phạm vi của ý niệm cá nhân hóa trong một cuộc bàn luận về nội thất, lĩnh vực chuyên môn của ông. Morris cho rằng cách chế tạo bàn ghế truyền thống cho phép các nghệ nhân nhìn thấy bản thân mình phản chiếu trên tính chất của những đồ vật họ tạo ra. Mỗi chiếc ghế làm thủ công đều riêng biệt như chính người đã làm ra nó. Trong thời kỳ tiền công nghiệp, hàng nghìn người ở khắp nơi tham gia thiết kế ghế và mỗi một nghệ nhân đều có thể phát triển những ý tưởng với sắc thái khác nhau về một chiếc ghế đẹp sẽ như thế nào

Nhưng một phần không thể tránh khỏi trong chủ nghĩa tư bản là quá trình tập trung và chuẩn hóa. Tiền, chuyên môn, ảnh hưởng thị trường và các hệ thống phân phối tinh vi có xu hướng tập hợp lại bởi một vài con người tầm cỡ, người đè bẹp và nghiền nát đối thủ để đạt được vị trí chí tôn trên thị trường. Những rào cản gia nhập gia tăng theo câp số mũ. Hoạt động quản lý tài chính tốt có thể cắt giảm chi phí, chú tâm nghiên cứu thị hiếu tiêu dùng, áp dụng công nghệ tiên tiến nhất và cung cấp sản phẩm thu hút người tiêu dùng với giá cả tốt nhất có thể. Kết quả là, sản xuất kiểu nghệ thuật không thể cạnh tranh nổi, Morris đã nhận ra điều đó khi xưởng truyền thống mà ông thành lập để chế tạo ghế cho tầng lớp trung lưu thời Victoria bị buộc phải thanh lý tài sản sau chiến tranh giá cả.

Ngày nay tất nhiên vẫn còn một số ít nhà thiết kế nội thất, một số người còn rất nổi tiếng, nhưng điều này không thể che đậy một sự thật rằng ta gọi “thiết kế” là một lĩnh vực khác thường, một thị trường ngách chỉ tuyển dụng rất ít nhân lực. Đa số những người liên quan đến công việc làm ra và buôn bán nội thất sẽ không hề có cơ hội để lại dấu ấu của bản thân trên những đồ vật ấy. Thay vào đó họ thuộc về một đội quân lao động hiệu suất cao nhắm đến những công đoạn vô danh nghiêm ngặt.

Dù không mang mục đích thiếu quan tâm hay thờ ơ với niềm vui trong công việc, chủ nghĩa tư bản đã làm giảm đáng kể số lượng công việc cho phép sự cá nhân hóa.

Ví dụ, chiếc ghế Eames, được thiết kế bởi Charles và Ray Eames, được đưa vào sản xuất năm 1956. Đây là một sản phẩm độc đáo phản ánh sâu sắc những lý tưởng và triển vọng của người đã thiết kế ra nó. Nếu họ là những thợ thủ công, làm việc tại nhà xưởng nhỏ, có lẽ cả đời họ chỉ bán được vài chục chiếc ghế như thế cho khách địa phương. Thay vào đó, vì họ làm việc dưới chế độ tư bản cho Herman Miller – một văn phòng thương mại và tập đoàn sản xuất nội thất nhà cửa khổng lồ – hàng trăm nghìn sản phẩm được bán suốt nhiều thập kỷ cho đến ngày nay. Thành công này cũng đã thâu tóm thị trường ghế có thiết kế đẹp. Ngày nay bất cứu ai muốn làm ra một chiếc ghế công sở đều phải đối mặt với việc hiện tại người ta đã có khả năng mua một chiếc ghế rất tốt, được thiết kế bởi hai thiên tài, và được giao hàng nhanh chóng bởi một công ty toàn cầu với mức giá cạnh tranh và mạng lưới chi nhánh rộng lớn.

Ta đã quá quen với ý niệm rằng tài sản của thế giới hầu hết nằm trong lòng bàn tay của một nhóm rất ít người – nhóm 1% khét tiếng. Nhưng chủ nghĩa tư bản không chỉ đem lại tiền bạc. Có một sự thật chua chát hơn, ít người biết hơn, rằng chỉ có rất ít người – một nhóm 1% khác với nhóm trên, nhưng cũng có một số người thuộc cả hai nhóm – có thể làm một công việc thú vị, một công việc được “cá nhân hóa”.

Điều này cho thấy chúng ta cuồng những cá nhân thiên tài. Xã hội của chúng ta tôn sùng những câu chuyện về hành trình khai phá của những công ty khởi nghiệp xuất sắc, những tín đồ thời trang đầy màu sắc, những nhà làm phim và nghệ sĩ xuất chúng, nhũng con người nhào nặn thế giới theo hình ảnh của riêng mình và để lại con dấu cá nhân trên những gì họ làm và những vật họ tạo ra. Có thể ta nghĩ mình quan tâm đến những con người ấy để tìm kiếm nguồn cảm hứng. Nhưng có khi ta đang lợi dụng họ để bù đắp cho những khoảng trống đau thương của chúng ta. Những câu chuyện cá nhân hóa thành công hiện ra vào lúc cơ hội công việc cá nhân hóa trên thực tiễn đã tan biến – cũng giống như ở thế kỷ 19, thời kỳ di cư hàng loạt đến thành thị, những tiểu thuyết về cuộc sống nông thôn nhận được sự yêu thích chưa từng có từ độc giả đô thị. Qua sự ham muốn những câu chuyện về các thiên tài sáng tạo đơn độc, có thể ta đang cố gắng vẽ nên nguồn sống từ những phẩm chất thiếu thốn đến thảm thương trong cuộc sống công việc hàng ngày.

Mức độ phổ biến của những câu chuyện về cá nhân sáng tạo nuôi dưỡng ảo tưởng rằng công việc cá nhân hóa bình thường hơn hơn thực tế. Rất nhiều cuộc phỏng vấn và hồ sơ cho thấy sự thật là – đối với hầu hết chúng ta – gần như không thể nào cạnh tranh nổi với những thế lực chuẩn hóa khổng lồ. Vì lý do này, chứ không phải do ta đã làm gì sai, đa số chúng ta có khuynh hướng cảm nhận phần lớn công việc của mình rất tẻ nhạt và không có chút cơ hội nào để chạm khắc nên con gargoyle của riêng mình.

(còn tiếp)

Thế Giới Di Động & Điện Máy Xanh làm Thương mại điện tử – Nghe mà thấm!

Với tốc độ tăng trưởng cán mốc 22%/ năm, thị trường thương mại điện tử Việt Nam (TMĐT) vừa là “miếng bánh hấp dẫn” với nhiều doanh nghiệp vừa là đấu trường cạnh tranh khốc liệt, mà chỉ khi sở hữu những chiêu thức riêng mới có thể đạt được thành công như mong muốn. Tại Việt Nam, Thế Giới Di Động & Điện Máy Xanh (TGDĐ& ĐMX) là 2 doanh nghiệp như thế!

Thế Giới Di Động có hơn 1.500 siêu thị, 31.000 nhân viên phủ khắp 63 tỉnh thành, Điện Máy Xanh có gần 600 siêu thị, liệu công nghệ – phần mềm quản trị – quy trình kĩ thuật nào có thể đảm đương được toàn bộ hệ thống này?

Theo chia sẻ của anh Nguyễn Thanh Tùng (Tùng Jacob) – Trưởng bộ phận phát triển Web app của Thế Giới Di Động & Điện Máy Xanh – VWS tại Tp.HCM vừa qua, các bộ phận liên quan TMĐT trong mô hình Omnichannel tại TGDĐ & ĐMX sẽ được phân thành 4 bộ phận chính hỗ trợ nhau tối đa:

  • Đưa ra yêu cầu: ngành hàng, hãng sản xuất
  • Triển khai: phát triển bán hàng, Marketing online, IT, Thiết kế/ Product, Nội dung media
  • Bán hàng: call center, Live chat, trả lời comment
  • Hỗ trợ chính: siêu thị (gọi, giao), sau bán hàng (giao, lắp đặt), đối tác giao hàng, hỗ trợ kỹ thuật, chăm sóc khách hàng, kiểm soát vận hành online.

Anh Tùng còn so sánh việc làm E-commerce cũng giống như xây dựng 1 ngôi nhà mà trong đó: Website, Sản phẩm – Dịch vụ và Trải nghiệm khách hàng chính là phần nổi mà chúng ta thấy được và phần nền móng bên dưới sẽ là Văn hóa công ty – Giá trị cốt lõi, Mindset (tư duy), Chính sách, Cách vận hành & Công nghệ thông tin.

Cụ thể, về trải nghiệm khách hàng, anh đã đưa ra 1 case study đáng học hỏi của Amazon xuất phát từ châm ngôn “Khách hàng là thượng đế”: Khách hàng vừa mua Apple TV & đang trên đường tới nhận hàng thì trên store Amazon có chính sách giảm giá 10% khiến vị khách này không hài lòng, khiếu nại yêu cầu giảm giá. Kết quả là, Amazon đã lập tức hoàn ngày 10% – một hành động này tuy nhỏ nhưng để thực hiện được lại không hề dễ dàng.

Về chính sách, với mô hình Omnichannel hiện tại, sẽ phải cần sự liên kết các bộ phận vào 1 mục tiêu chung hỗ trợ tối đa cho các hoạt động online. Chính sách này đảm bảo 3 bộ phận là Ngành Hàng, Marketing Online, Phát triển bán hàng online hiểu và thống nhất với nhau vì trên thực tế, mỗi bộ phận lại quan tâm đến những yếu tố khác nhau:

  • Ngành hàng chỉ quan tâm đến Doanh thu ngành hàng, Lãi gộp, Lợi nhuận
  • Marketing online chỉ quan tâm đến Paid traffic, tỷ lệ click & mua hàng
  • Phát triển bán hàng online chỉ quan tâm đến Doanh thu online

Giải pháp mà tập đoàn đưa ra là áp dụng KPI chung cho cả 3 bộ phận là Doanh thu Online. Chẳng hạn thu nhập mỗi team hoặc mỗi cá nhân sẽ đươc tính từ % lượng cộng với % thưởng gồm % KPI chính & % KPI doanh thu online hàng tháng.

Về vận hành, đội ngũ Thế Giới Di Động & Điện Máy Xanh có 1 thuật ngữ riêng áp dụng cho hàng viễn thông, phụ kiện & gia dụng nhỏ có sẵn tại siêu thị. Thuật ngữ này gọi vui là “Uber” giao hàng với cam kết trong 30 phút sẽ giao hàng được ngay cho khách hàng có nhu cầu. Kết quả đáng kinh ngạc này thực hiện được không chỉ dựa vào số lượng siêu thị lên đến con số 1500 trải rộng khắp toàn quốc mà còn dựa vào cơ chế vận hành hoàn toàn mới. Khi có 1 yêu cầu đặt hàng, thay vì đưa về call center để xác thực rồi mới chuyển đến siêu thị gần nhất như truyền thống, cơ chế mới sẽ sử dụng server tính toán order của khách hàng, chuyển ngay đến siêu thị gần nhất hoặc thậm chí là chuyển trực tiếp đến nhân viên còn trống tải để đi giao trong vòng 30 phút. Cách vận hành này không chỉ tăng tỷ lệ xử lý đơn hàng tự động, giảm tải cho call center mà bằng việc đẩy cho siêu thị “follow up” đơn hàng, chúng ta sẽ tăng được tỷ lệ chốt đơn hàng thành công.

Tech team của Thế Giới Di Động & Điện Máy Xanh cũng tích hợp các công cụ tư vấn – xử lý đơn hàng thường dùng (CRM) lên website chính, giảm thời gian & tăng sự thuận tiện khi nhân viên call center tư vấn cho khách.

Về phía nhân sự, tập đoàn E-commerce hàng đầu Việt Nam này luôn cố gắng nâng “chất” nhân viên tư vấn call center khi nhân viên call center hiện nay phải nghe & xử lý đơn hàng của nhiều website, sử dụng nhiều kỹ năng & công cụ hơn như: nghe gọi – xử đơn hàng – live chat.

Ngoài ra, nhân viên lẫn Ban lãnh đạo của Thế Giới Di Động & Điện Máy Xanh luôn cố gắng mở hết “tai mắt” lắng nghe khách hàng, thực hiện “vi hành” mua hàng trên thực tế, không chỉ mua của Thế Giới Di Động & Điện Máy Xanh mà còn trên các trang của đối thủ cạnh tranh. Đặc biệt, Tech team đã gắn box bình luận ở mọi chỗ trên site để thường xuyên theo dõi các bình luận, nhất là bình luận trên các landing page bán hàng nhằm tối ưu liên tục trong quá trình thực hiện các chương trình bán hàng, giảm giá…

Anh Tùng Jacob cũng nhấn mạnh việc kết nối giữa nhân sự mỗi team như khi xây dựng 1 chương trình Marketing/ bán hàng, đội ngũ có trách nhiệm cần trao đổi với các khối hỗ trợ để lường trước mọi tình huống, đặc biệt chú ý đến tải phục vụ như khả năng trực tổng đài, khả năng lắp đặt, khả năng giao nhận…

Kết thúc bài chia sẻ, anh Thanh Tùng đưa ra 4 điểm chính mà các doanh nghiệp đã, đang và sẽ dấn thân vào lĩnh vực E-commerce cần đặc biệt quan tâm để tối ưu trong năm 2018:

  • Cá nhân hóa trải nghiệm trên website
  • Thử nghiệm các hình thức content “chất” giúp tăng tỷ lệ chuyển đổi
  • Chatbot thay thế dần cho Live chat
  • Mobile hóa các công cụ làm việc: CMS, CRM, Xử lý đơn hàng, Live chat sẽ dễ dàng, đạt hiệu quả cáo trên Mobile thay vì Desktop.

Như vậy, Thế giới Di động & Điện Máy Xanh đã đưa ra hàng loạt các giải pháp công nghệ hiệu quả để nắm rõ “đường đi nước bước” của từng đơn hàng, từng mẫu sản phẩm, quy trình hoạt động của nhà kho, cửa hàng, nhân viên. Nhờ những công cụ kĩ thuật mà Tech team xây dựng, hầu như tất cả các thao tác trong các hoạt động của các bộ phận từ nhân sự, cung ứng, Maketing, hành chính, quản lý…. đều được tự động hóa một cách tối đa, tiết kiệm rất nhiều nhân lực, giúp các quy trình vận hành mượt mà, nhanh và chính xác nhất.

Cùng với tư tưởng tất cả hướng về khách hàng, Thế Giới Di Động & Điện Máy Xanh đã thực sự mang đến những trải nghiệm tuyệt hảo, góp phần khẳng định giá trị thương hiệu & xây dựng lòng trung thành, sự tín nhiệm lâu dài.

Thông tin chi tiết về sự kiện Vietnam Web Summit ở Hà Nội:

  • Thời gian & địa điểm: 08/12/2017 tại CTM Palace, 131 Nguyễn Phong Sắc, Dịch Vọng Hậu, Cầu Giấy, Hà Nội
  • Website: https://vietnamwebsummit.com/
  • Fanpage chính thức: https://www.facebook.com/Vietnamwebsummit/

Về các hạng mục hợp tác tại sự kiện: Mr. Lê Đặng Hiếu | 0121 764 2405 | hieuld@applancer.net

Hotline: BTC | 84-28 62645022 | 84-28 62733496 | 84-28 62733497 | event@applancer.net

Nỗi sầu công việc (Chương 1)

Công việc khiến ta thất vọng không phải là ngẫu nhiên, mà là không thể tránh khỏi vì ít nhất là 8 lý do tâm điểm.

Mọi người đều có một cảm xúc chung về công việc, đó là thất bại. Ta thất bại vì ta kiếm ít tiền hơn mong muốn, vì ta bị cho ra rìa trong tổ chức của mình, vì rất nhiều người thân quen của ta thành công, vì kế hoạch của ta vẫn còn đang nằm trên bảng vẽ, vì ta luôn cảm thấy lo lắng và vì ta vẫn luôn, đã từ lâu rồi, rất rất buồn chán.

Ta thường nhìn nhận nỗi sầu thảm của mình trong thâm tâm. Ta tin rằng thất bại có liên hệ mật thiết với tính cách và những sự lựa chọn của mình. Nhưng có một đề xuất cho rằng nguyên nhân lớn nhất dẫn đến thất bại nằm ở thứ mà những người có ý thức, khiêm tốn bình thường đều chán ghét theo bản năng: cái hệ thống ta đang sinh sống. Dù có do dự thế nào, có vẻ như ta đều xứng đáng để nhận định lại ít nhất là một số lời giải thích cho những khốn khổ của mình, không phải từ trải nghiệm cá nhân mà hướng đến những tác động lịch sử và kinh tế quy mô lớn. Dù trong cuộc sống hàng ngày, ta thường vướng vào những rắc rối (những sai lầm, ham muốn, hoảng loạn) khiến ta cảm thấy đó đều là trách nhiệm của bản thân, nhưng nguyên nhân thực sự có thể không phải ở chúng ta mà nằm ở dòng chảy lịch sử to tát, quy mô hơn: nằm ở cách cơ cấu các ngành công nghiệp, cách các chuẩn mực được định ra và cách các giả thiết của chúng ta được thành lập. Chủ nghĩa tư bản từ lâu nay vẫn luôn là một chế độ rất khó để duy trì sự cân bằng, tìm kiếm thanh thản trong tâm hồn, thỏa mãn trong công việc – và rất khó để đối phó. Lỗi không hẳn là ở ta nếu như có lúc – thực chất là rất thường xuyên – ta cảm thấy như một kẻ thất bại.

Bài viết này không nhằm mục đích đào sâu vào chủ nghĩa tư bản, hay đề xuất một chế độ khác dễ dàng hơn. Mọi nền kinh tế từng hiện diện đều ràng buộc với một vài nỗi sầu khổ. Tổ chức một hệ thống công bằng với những khuyến khích, tưởng thưởng và kích thích nằm ngoài khả năng của chúng ta. Ta nên được phép đưa ra những chỉ trích, không phải với mục đích tranh cãi về một chế độ sống lý tưởng, mà là để tách suy nghĩ thất bại ra khỏi bản thân.

Công việc khiến ta thất vọng không phải là ngẫu nhiên, mà là không thể tránh khỏi vì ít nhất tám lý do tâm điểm:

vì quy mô ngành công nghiệp đã cướp đi ý nghĩa của chúng ta,

vì yêu cầu chuyên môn hạn chế tiềm năng của chúng ta,

vì mối quan tâm tư bản vắt kiệt những sáng kiến riêng,

vì giới hạn sự lựa chọn của người tiêu dùng buộc ta phải thương mại hóa sản phẩm của mình quá mức chấp nhận được,

vì cạnh tranh tạo nên những mối lo âu vô hạn,

vì nhu cầu hợp tác khiến ta phát điên,

vì những tham vọng lớn lao khiến ta cay đắng và

vì ý niệm thế giới coi trọng nhân tài đặt lên vai ta gánh nặng trách nhiệm cho những thất bại của mình.

Hiểu được những nỗi sầu khổ của công việc không xóa bỏ chúng một cách thần kỳ, nhưng ít nhất điều này sẽ làm vơi bớt gánh nặng suy nghĩ rằng mình ngu lắm vụng về lắm nên mới phải chịu đựng những bất hạnh này.

Chuyên môn hóa

Một trong những nỗi sầu lớn nhất trong công việc bắt nguồn từ suy nghĩ chỉ một phần rất nhỏ tài năng của ta được áp dụng trong công việc ta làm hằng ngày. Ta có thể làm được nhiều hơn rất nhiều so với những gì công việc ta đảm nhận cho phép. Chức danh trên tấm danh thiếp chỉ là một trong hàng nghìn chức danh ta sở hữu theo lý thuyết.

Trong bài “Song of Myself” (Bài hát về bản thân tôi), xuất bản năm 1855, nhà thơ người Mỹ Walt Whitman đã đưa ra một câu nói đáng nhớ: “Tôi vĩ đại, trong tôi chứa đựng vô vàn điều  hay” – ý ông là trong mỗi cá nhân đều có rất nhiều phiên bản thú vị, hấp dẫn và tài năng, vì vậy nên mỗi người có rất nhiều cách tốt để sống và làm việc, nhưng hiếm trong số đó thực sự trở thành hiện thực trong cuộc đời duy nhất của chúng ta. Thế nên ta luôn âm thầm và đau đớn suy ngẫm về những định mệnh không được hoàn thành – và đôi lúc nhận ra trong khổ sở rằng mình đáng lẽ có thể trở thành một điều gì đó khác, một con người khác.

Một lý do lớn cho việc tại sao ta không thể khám phá tiềm năng của bản thân là vì ta thu được nhiều hơn khi không làm điều đó. Trong quyển The Wealth of Nations (Sự Thịnh Vượng Của Các Quốc Gia), xuất bản năm 1776, nhà kinh tế học và triết học người Scotland Adam Smith lần đầu tiên giải thích vì sao “phân công lao động” là trung tâm dẫn đến gia tăng năng suất của chủ nghĩa tư bản. Smith nhấn mạnh vào sự hiệu quả chói lọi có thể đạt được trong sản xuất cái ghim, nếu mọi người tập trung vào một nhiệm vụ nhỏ hẹp (và ngừng khám phá “những đa dạng” trong bản thân):

Một người kéo sợi dây ra, người khác duỗi thẳng, người thứ ba cắt, người thứ tư mài nhọn, người thứ năm dũa để gắn phần đầu vào; để làm phần đầu cần hai đến ba thao tác riêng biệt; lắp ráp là một công đoạn riêng, tẩy trắng là một công đoạn khác nữa; và ghim nó vào giấy cũng là một cuộc đổi chác; và theo cách này, ngành công nghiệp chế tạo một cái ghim được chia làm khoảng mười tám công đoạn khác nhau, tất cả được thực hiện bằng những bàn tay khác nhau. Tôi đã thấy một xưởng sản xuất nhỏ có thể cho ra trên bốn mươi tám nghìn chiếc ghim một ngày. Nhưng nếu mỗi người trong số họ làm tách biệt và độc lập, và không ai trong số họ được đào tạo về toàn bộ quy trình của ngành kinh doanh này, trong một ngày họ có lẽ chẳng tạo ra nổi một chiếc ghim.

– Adam Smith, The Wealth of Nations, Quyển 1, Chương 1 Of the Division of Labour (Phân công lao động)

Adam Smith

Adam Smith dự liệu như thần. Làm một công việc duy nhất trong hầu hết cuộc đời mang lại ý nghĩa kinh tế hoàn hảo. Nhờ cái thế giới mà Smith đã tiên đoán trước – và góp phần biến nó thành hiện thực – mà hiện tại chúng ta đang làm những công việc chuyên môn như thế, và ta có những chức danh như Thiết kế Bao bì & Thương hiệu Cấp cao, Bác sĩ Tiếp nhận và Phân chia, Quản lý Trung tâm Nghiên cứu, Chuyên viên kiểm soát Rủi ro và Kiểm toán nội bộ và Chuyên viên tư vấn Chính sách Vận chuyển. Ta đã trở thành những chiếc bánh răng tí hon, tương đối giàu có trong bộ máy hiệu suất khổng lồ. Tuy vậy, trong những phút giây trầm lặng, ta lại soi vào những ao ước riêng tư được thể hiện những phiên bản đa dạng của bản thân.

Một trong những độc giả uyên bác và sáng suốt nhất của Adam Smith là nhà kinh tế học người Đức Karl Marx. Marx hoàn toàn đồng tình với phân tích của Smith; chuyên môn hóa thực sự đã thay đổi thế giới và sở hữu năng lực cách mạng để làm giàu cá nhân và quốc gia. Nhưng điểm khác biệt giữa ông và Smith là cách ông thẩm định sự phát triển này sẽ được kỳ vọng đến đâu. Ta chắc chắn có thể khiến bản thân giàu có hơn bằng cách chuyên môn hóa, nhưng ta cũng – như điều Marx chỉ ra với niềm đam mê – khiến cuộc sống trở nên tẻ nhạt và thui chột tài năng. Khi mô tả xã hội Cộng sản không tưởng của mình, Marx nhấn mạnh rất kỹ vào ý niệm mỗi người đều có nhiều công việc khác nhau. Sẽ không có chuyên. Trong một đoạn nói về Smith, Marx đã viết:

Trong xã hội cộng sản… không ai có một lĩnh vực hoạt động riêng biệt mà mỗi người đều có thể đạt được thành tựu trong bất kỳ con đường nào họ muốn… vì vậy tôi có thể làm một việc ngày hôm nay và một việc khác vào ngày mai, săn bắn vào buổi sáng, câu cá vào buổi trưa, chăn nuôi gia súc vào buổi chiều, phê bình sau bữa tối… mà không cần phải trở thành thợ săn, ngư dân, người chăn trại hay nhà phê bình.

– Karl Marx, The German Ideology (Tư tưởng người Đức) (1846)

Một số lý do cho việc tại sao công việc ta đang làm (và công việc ta không làm) lại quan trọng đến vậy là vì nghề nghiệp là yếu tố quyết định hình hài con người chúng ta. Ta thường rất khó để nhận ra tính cách của chúng ta bị ảnh hưởng bởi công việc như thế nào, những góc nhìn ấy rất tự nhiên đối với chúng ta, nhưng ta có thể quan sát được bản chất định hình-định danh của công việc ở người của lĩnh vực khác. Giáo viên tiểu học đối xử với cả người trung niên như thể họ cần được chăm nom kỹ lưỡng, nhà phân tâm học được học cách lắng nghe và tỏ vẻ không xét nét khi để thoát ra một hơi thở ưu tư phản xạ, chính trị gia cuốn trôi trong những bài phát biểu trong bữa tiệc tối thân mật. Mọi nghề nghiệp làm yếu đi hoặc củng cố những khía cạnh trong bản chất của chúng ta. Có những công việc khiến ta bị bó buộc vào khoảnh khắc tức thì (y tá cấp cứu, biên tập thời sự), một số khác rèn luyện sự tập trung vào những rìa xa hơn của dòng thời gian (nhà tương lại học, quy hoạch đô thị, trồng rừng). Những công việc cụ thể mài sắc những nghi ngờ đối với con người, cho rằng sự thật luôn khác xa những gì người ta nói công khai (nhà báo, buôn bán đồ cổ), số khác lại bắt gặp con người tại những thời điểm vô tư, chân thành trong cuộc đời của họ (nhà gây mê, thợ làm tóc, người khâm liệm). Trong một số công việc, điều bạn cần làm để tiến lên được thăng chức là rất rõ ràng (công chức, luật sư, bác sĩ phẫu thuật), động lực đem lại sự điềm tĩnh và bình ổn cho tâm hồn, và giảm thiểu khuynh hướng lập mưu bày kế; trong khi ở những công việc khác (sản xuất chương trình truyền hình, chính trị gia), luật lệ rất lỏng lẻo và thường gắn liền với tình bạn tình cờ và liên minh ngẫu nhiên, gia tăng tỷ lệ lo âu, hoài nghi và lệch lạc.

Tâm lý học liên quan đến công việc không chỉ ở yên chốn công sở, nó tô vẽ nên con người mà chúng ta sẽ trở thành. Ta bắt đầu hành xử theo cách công việc đòi hỏi ở ta xuyên suốt cuộc đời. Đồng thời, nó sẽ thu hẹp tính cách của chúng ta. Khi những cách suy nghĩ nhất định được triệu hồi thường xuyên, người khác sẽ bắt đầu cảm thấy kỳ dị và bị đe dọa. Bằng cách hy sinh một phần lớn cuộc sống cho một nghề nghiệp chuyên môn, người ta cần phải đánh mất cân bằng của những lĩnh vực tiềm năng ẩn giấu khác. Công việc có thể khuếch trương tính cách, và công việc cũng sở hữu năng lực mạnh mẽ để cầm tù tinh thần của chúng ta.

Ta có thể đặt ra câu hỏi tự truyện chua chát rằng ta sẽ trở thành một người như thế nào nếu ngày trước có cơ hội làm một điều gì đó khác. Có một số phần trong bản thân mà ta phải giết chết hoặc nhấn chìm trong bóng tối, nhưng lại giật nhao nhao lên mỗi chiều chủ nhật. Trên những con đường sự nghiệp khác kia chính là những phiên bản khác của con người chúng ta – khi ta có cái gan để suy tưởng về điều ấy, chúng sẽ bộc lộ ra những nhân tố quan trọng, nhưng đã bị hy sinh và chưa được phát triển, trong tính cách của chúng ta.

Ta được định chỉ gắn bó với một công việc duy nhất, nhưng lại thực sự có tài năng ở rất nhiều công việc mà ta không có cơ hội để khám phá hết. Ta có thể hiểu nguồn gốc của sụ bồn chồn ấy khi nhìn lại về tuổi thơ. Khi còn nhỏ, trong một buổi sáng chủ nhật, có khi ta mặc thêm một cái áo liền quần và tưởng tượng mình là nhà thám hiểm Bắc cực, sau đó lại có một khoảng thời gian ngắn làm kiến trúc sư xây một căn nhà Lego, một ngôi sao nhạc rock sáng tác bài hát về ngũ cốc và nhà phát minh tìm cách tô màu nhanh hơn bằng cách dán bốn cây bú màu lại với nhau; ta dành một vài phút làm thành viên đội cứu hộ khẩn cấp sau đó thử làm phi công hạ cánh máy bay chở hàng một cách xuất sắc trên thảm hành lang; ta thực hiện phẫu thuật cứu người trên con thỏ len và cuối cùng ta làm bếp phó giúp chuẩn bị sandwich giăm bông phô mai cho bữa trưa. Mỗi một “trò chơi” đều có thể là khởi đầu của một sự nghiệp. Nhưng ta chỉ đưa ra một sự lựa chọn duy nhất, và thực hiện công việc ấy lặp đi lặp lại trong suốt 50 năm.

So với trò chơi khi bé, ta đang sống một cuộc sống hạn chế đến tàn nhẫn. Không có phương thuốc dễ dàng nào cả. Theo lời Adam Smith, nguyên nhân không nằm ở lỗi cá nhân mà ta phạm phải. Đó là một giới hạn đè nặng lên ta bởi luận lý về một nền kinh tế thị trường cạnh tranh, năng suất cao. Nhưng ta có thể cho phép bản thân than khóc rằng sẽ có nhiều khía cạnh trong tính cách của chúng ta không được thỏa mãn. Ta không ngốc nghếch hay vô ơn. Đó đơn giản chỉ là xung đột giữa nhu cầu tuyển dụng thị trường và tiềm năng rộng lớn, không bị bó buộc của mỗi con người. Cái nhìn này mang lại chút ưu buồn. Nhưng nên nhớ rằng cảm giác không trọn vẹn này sẽ luôn theo ta trong bất kỳ ngành nghề nào ta chọn: ta không nên cố gắng vượt qua nó bằng cách đổi ngành. Không có một công việc nào là đủ cả.

Có một so sánh song song giữa trải nghiệm xung quanh công việc và những chuyện xảy ra trong các mối quan hệ. Chắc chắn là ta có thể có những mối quan hệ tốt với hàng chục, hay hàng trăm người khác nhau (mà không bị bạn đời hiện tại trách móc). Họ sẽ phơi bày ra những mặt khác trong tính cách của ta, khiến ta hài lòng (và tức giận) theo nhiều cách khác nhau và giới thiệu với ta những niềm vui mới. Tuy nhiên, đối với công việc, chuyên môn hóa mang lại nhiều lợi thế: điều đó có nghĩa ta có thể tập trung, nuôi dạy con cái trong một môi trường ổn định, và học những nguyên tắc thỏa hiệp. Trong tình yêu và công việc, cuộc sống đòi hỏi ta phải là có chuyên môn dù bản chất ta phù hợp với việc khám phá trường kỳ. Và vì thế ta mang theo trong lòng, dưới hình hài của những phôi thai, rất nhiều phiên bản quyến rũ của bản thân mà ta không bao giờ có cơ hội thực hiện. Đó là suy nghĩ ảm đạm nhưng cũng an ủi. Những khổ nhọc của ta rất đau đớn nhưng nó cũng có một phẩm giá lạ kỳ, vì với ai nó cũng như thế. CEO cũng như thực tập sinh, họa sĩ cũng như kế toán. Ai cũng có thể tìm thấy rất nhiều phiên bản hạnh phúc đang trốn tránh họ. Chịu đựng đau khổ này, ta đang là một con người bình thường. Ta có thể xóa trang tìm kiếm việc làm khỏi mục dấu trang và hủy đăng ký trang hẹn hò với niềm tự hào u uất khi nhận ra sự thật rằng – dù ta có làm gì – một phần tiềm năng của ta vẫn sẽ không được phát triển và phải chết đi mà không có cơ hội được lớn lên – để phục vụ cho lợi ích của sự tập trung và chuyên môn hóa.

Nguồn bài: tamlyhoctoipham.com

(còn tiếp)