Home Blog Page 160

Debug và khắc phục lỗi hiển thị ký tự Unicode của ứng dụng Web

Debug và khắc phục lỗi hiển thị ký tự Unicode của ứng dụng Web

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

Tác giả: Nguyễn Bình Sơn

Bài viết này ngầm định rằng bạn biết “bảng mã” nghĩa là gì, và bạn quen thuộc với các thành phần của mô hình ứng dụng web cũng như mô hình trình diễn MVC. Mặc dù mã ở đây được trình bày dưới dạng thức của ngôn ngữ Java, framework Spring MVC và database MySQL, các vấn đề được nhắc đến là chung, các khái niệm được nhắc đến là phổ biến, và các cách giải quyết là tổng quát. Hãy cùng tìm hiểu về Debug và khắc phục lỗi hiển thị ký tự Unicode của ứng dụng Web nhé!

  Debug và khắc phục lỗi hiển thị ký tự Unicode của ứng dụng Web
”]

  Một số tip debug trong Laravel

Model mang dữ liệu Unicode nhưng View thì không

Bạn có model như thế này.

Nhưng bạn nhận được kết quả như thế này:

Là vì View của bạn có nội dung như thế này:

CREATE DATABASE IF NOT EXISTS cms CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Bạn cần làm cho view engine render cho bạn một view mà trong đó các ký tự unicode của template và model được bảo toàn. Ví dụ sau đây là cấu hình cho view engine Thymeleaf.

@Bean
public ViewResolver viewResolver() {
    // ...
    viewResolver.setCharacterEncoding("UTF-8");
    return viewResolver;
}

Template mang ký tự Unicode nhưng View thì không

Bạn có view template như thế này:

<tr>
  <td>Tên</td>
  <td>
    <input type="text" name="name" th:value="${customer.name}">
  </td>
</tr>
<tr>
  <td>Email</td>
  <td>
    <input type="text" name="email" th:value="${customer.email}">
  </td>
</tr>
<tr>
  <td>Địa chỉ</td>
  <td>
    <input type="text" name="address" th:value="${customer.address}">
  </td>
</tr>

Nhưng bạn nhận được view như thế này:

Nếu bạn đã xử lý vấn đề encoding trong lúc render như ở trên rồi, thì có thể vấn đề là do template resorver đã dùng một encoding khác để đọc tài liệu template. Hãy cấu hình lại cho cả template resolver nữa.

@Bean
public ITemplateResolver templateResolver() {
    // ...
    templateResolver.setCharacterEncoding("UTF-8");
    return templateResolver;
}

Không thể chuyển tải ký tự Unicode qua tầng giao vận

Giả sử cần submit form sau:

Tầng giao vận TCP/IP không quan tâm với bảng mã, nó đơn giản và vận chuyển gói tin, từng byte một. Phần lớn web server, trừ khi là web server do bạn tự viết, decode các bytes này để có các parametter theo lối như thể rằng các bytes đó trước kia là ký tự của bảng mã ISO-8859–1. Nếu bạn nhìn các ký tự đã được decode ra dưới con mắt của bảng mã UTF-8 (trớ trêu rằng, phần lớn các ngôn ngữ lập trình làm như thế), bạn sẽ nhận được kết quả không mong muốn.

Cách xử lý luôn luôn là encode chuỗi ký tự ngược lại thành dòng bytes (theo bảng mã ISO-8859–1, tất nhiên), và sau đó decode lại theo bảng mã UTF-8. Cho dù là thủ công như sau:

public String createCustomer(Customer customer) {
    try {
        byte[] bytes = customer.getName().getBytes("ISO-8859-1");
        String decodedName = new String(bytes, "UTF-8");
        customer.setName(decodedName);
        customerService.save(customer);
        return "redirect:/customers";
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
        return "500";
    }
}

… hay tự động, bằng cách sử dụng filter, như sau chẳng hạn:

public class AppInit extends AbstractAnnotationConfigDispatcherServletInitializer {
    // ...    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        FilterRegistration.Dynamic filterRegistration =
            servletContext.addFilter("endcoding-filter", new CharacterEncodingFilter());
        filterRegistration.setInitParameter("encoding", "UTF-8");
        filterRegistration.setInitParameter("forceEncoding", "true");
        
        //make sure encodingFilter is matched most first, by "false" arg
        filterRegistration.addMappingForUrlPatterns(null, false, "/*");
        
        super.onStartup(servletContext);
    }
}

Entity mang thông tin Unicode, vào đến Database thì mất dấu

Bạn có form như thế này:

Entity ngon nghẻ như thế này:

Vào tới database thì loạn cào cào hết cả:

Hầu hết các client của các dbms, khi kết nối tới dbms server, đều chọn mặc định một bảng mã để làm việc với nhau. “Mặc định” này đôi khi là một giá trị cố định, đôi khi là lấy dynamic. Dù là trường hợp nào đi chăng nữa, đôi khi charset đó hoàn toàn khác với charset được dùng cho Schema/Table/Column. Nghĩa là “anh nói tiếng của anh, nhưng tôi hiểu theo tiếng của tôi”.

Cách xử lý luôn là cố định lại bảng mã dùng trong cuộc nói chuyện giữa client và dbms server:

CREATE DATABASE IF NOT EXISTS cms CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Và đồng thời (điều này rất quan trọng), sử dụng cùng một bảng mã đó cho Schema/Table/Column:

CREATE DATABASE IF NOT EXISTS cms CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Nếu database cùng với dữ liệu đã tồn tại, theo một bảng mã khác, cách xử lý luôn là sử dụng một kỹ thuật nào đó được dbms hỗ trợ để convert dữ liệu từ bảng mã cũ sang bảng mã mong muốn.

Bài viết gốc được đăng tải tại Tạp Chí Lập Trình

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

Xem thêm các  IT Jobs for Developer hấp dẫn tại TopDev

Tìm việc làm IT mùa dịch không hề khó như bạn nghĩ

tam viec lam

Tình hình doanh nghiệp

Tim viec lam mùa dịch là việc không hề dễ dàng vì dịch đã làm ảnh hưởng nặng nề rất nhiều đến việc kinh doanh của nhiều công ty, dù là thời điểm trong dịch hay hiện giờ thì cũng có khá nhiều công ty trong và ngoài nước cắt giảm nhân sự. Chính vì vậy, cơ hội tìm kiếm việc làm của người lao động thông thường khá khó khăn. Tuy nhiên đối với những ngành nghề đặc thù liên quan đến công nghệ như IT thì lại không bị ảnh hưởng quá nhiều, và các kỹ sư kỹ thuật có tỷ lệ % bị cắt giảm nhân sự rất thấp.

Doanh nghiệp về du lịch là bị ảnh hưởng nhiều nhất, rất nhiều công ty du lịch đóng cửa vì không có khách du lịch. Ngoài ra các ngày liên quan đến sản xuất như may mặc ở các xí nghiệp cũng bị ảnh hưởng nặng nề và buộc phải cắt giảm rất nhiều nhân viên

Dù là sau dịch như hiện tại thì nhu cầu tuyển dụng cũng không nhiều, rất nhiều công ty phải đóng băng hoặc phá sản, hàng quán thì trả mặt bằng, bán nhà trong khi đó nhu cầu tim viec lam thì lại tăng… Theo thống kê, gần 8 triệu người mất việc, nghỉ việc luân phiên do Covid-19, trong đó số người bị ảnh hưởng do giảm thu nhập lên tới hơn 17 triệu người. 

tim viec lam

Đó là tình hình không mấy lạc quan đối với những xí nghiệp sản xuất, tiêu thụ thông thường. Còn các ngành công nghiệp hiện đại có liên quan đến công nghệ thì vẫn có nhu cầu cấp thiết đối với nguồn lực công nghệ, từ duy trì cơ sở hạ tầng đám mây cho đến thiết kế các trang thương mại điện tử. Việc hạn chế những nơi đông người và tăng cường mua sắm trực tuyến khiến các doanh nghiệp chuyển đổi hành vi mua sắm tại điểm bán sang đẩy mạnh phát triển các nền tảng mua sắm online, dẫn đến nhu cầu tuyển dụng IT, lập trình viên hay các vị trí liên quan đến phát triển thương mại điện tử tăng cao. 

Lấy ví dụ như các vị trí lập trình viên như System Engineer, Developer hay Technical Product… đều đóng vai trò quan trọng trong các công ty Startup, công ty thiên về công nghệ, sàn thương mại điện tử, các vị trí đó được đăng tuyển khá nhiều để có thể hỗ trợ, điều chỉnh cho tình hình mua sắm tại nhà như hiện nay. 

Các kỹ sư công nghệ trở nên quan trọng hơn bao giờ hết khi Việt Nam và thế giới đang đối đầu với dịch bệnh. Ngành lập trình viên vẫn hoạt động và phát triển rất tốt như chưa hề có dịch Covid.

Không những thế, thậm chí trong tình hình dịch bệnh như thế này nhưng ngành lập trình vẫn còn đang thiếu hụt nhân sự vì nhu cầu nhân sự, nhu cầu tim viec lam của các lập trình viên thì vẫn có. Tuy nhiên, trong tình hình dịch ứng viên lại ngại các cuộc phỏng vấn trực tiếp sẽ là nguyên nhân gây lây nhiễm dịch bệnh. 

tim viec lam

Giải pháp tim viec lam mùa dịch

Vì để tránh tình trạng thiếu hụt nhân sự công nghệ, nhiều doanh nghiệp đưa ra giải pháp phỏng vấn online để có thể dễ dàng tiếp cận ứng viên hơn trong tình hình dịch bệnh như hiện nay. Ứng viên chỉ cần gửi so yeu ly lich kèm cv tiếng Việt hoặc cv tieng anh tùy vào yêu cầu của công ty ứng tuyển. Sau đó, nếu cv của ứng viên có thể lọt vào mắt xanh của nhà tuyển dụng nào đó thì sẽ nhận được mail mời phỏng vấn online.

Điểm thuận lợi của phỏng vấn online là có thể giúp cả đôi bên tiết kiệm thời gian, thời gian hẹn phỏng vấn cũng sẽ linh hoạt hơn vì không cần phải chuẩn bị quá nhiều thứ như khi gặp mặt nhau. Bên cạnh đó, ứng viên cũng có thể chủ động chọn lựa vị trí thuận tiện nhất để có cuộc phỏng vấn với nhà tuyển dụng mà không phải đi ra ngoài, chỉ cần nơi phỏng vấn của ứng viên chọn có wifi mạnh, backgound sáng sủa, gọn gàng.

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

  CEO TopDev ra mắt công nghệ AI/Computer Vision trợ giúp kết nối doanh nghiệp với người mất việc vì Covid

  Các công ty công nghệ Việt Nam và thách thức trong việc chuyển mình thời Covid - 19

  Tái tuyển dụng IT hiệu quả? Thách thức và cơ hội cho các công ty hậu Covid-19

 

Xem thêm Top IT Jobs lương cao trên TopDev

Mẫu CV xin việc Free cho các bạn IT

cv online

Với nhiều năm hoạt động trong ngành tuyển dụng lập trình viên TopDev tự tin rằng có thể cung cấp cho các bạn IT mẫu cv online chuẩn đẹp, free và đặc biệt là phù hợp nhu cầu ứng tuyển các vị trí khác nhau trong ngành lập trình.

Tại sao cần viết cv online?

Để có thể sở hữu được một bản cv online hoàn hảo, đầu tiên bạn cần hiểu được CV là gì và nó có ý nghĩa gì trong việc xin việc làm. Có thể hiểu nôm na CV là một bản tóm tắt sơ lược những công việc mà bạn đã làm qua, một bản CV luôn thể hiện được cho người đọc kinh nghiệm làm việc, học vấn, trình độ cá nhân…

Trước đây, khi công nghệ và nhu cầu tìm việc qua mạng còn ít thì những bản CV thường được viết tay hoặc đánh máy trên nền giấy A4. Sau này hiện đại hơn 1 tí thì có thể tạo CV bằng powerpoint, tuy nhiên khi bạn tự tạo CV thì sẽ mất khá nhiều thời gian vào nó, đặc biệt là những CV tự tạo đôi khi sẽ không được thẩm mỹ vì trình độ powerpoint của bạn có hạn, điều này sẽ gây ra ấn tượng xấu với nhà tuyển dụng.

Chính vì thấu hiểu những điều đó nên hiện nay có rất nhiều nền tảng cung cấp mẫu CV trên mạng với mẫu cv đa dạng, chỉnh chu hơn để hỗ trợ ứng viên tìm việc. Tuy nhiên điểm yếu của các mẫu CV này là sau khi hoàn thành xong phải tải về máy ngay, đôi khi muốn chỉnh sửa hay bổ sung một chi tiết nào đó thì phải làm lại từ đầu và tải lại thêm lần nữa, điều này rất phiền phức và làm rối tung folder của bạn.

  Cách viết CV giúp lập trình viên ghi điểm với nhà tuyển dụng

  5 mẹo và mẫu CV IT để gây ấn tượng với nhà tuyển dụng!

Mẫu CV online ra đời để giảm thiểu những khó khăn đó. Làm cv online sẽ giảm thiểu được tình trạng thường xuyên phải tải file về và việc sửa chữa cũng đơn giản tiện dụng hơn vì bạn chỉ cần điền theo form mẫu có sẵn cho từng ngành nghề. Bên cạnh đó các mẫu template CV onl hiện nay cũng rất đẹp, được các trang web đầu tư chỉnh chu, đặc biệt là các mẫu CV này hoàn toàn free ở 1 số mẫu và web. Ví dụ ở topcv thì free những mẫu cơ bản, cao cấp, đa dạng nhóm ngành…còn những mẫu chuyên nghiệp thì chỉ có tài khoản VIP được nạp tiền vào thì mới sử dụng được. Ở TopDev thì được tạo CV online free hoàn toàn và điểm mạnh ở TopDev là những mẫu CV này được thiết dựa theo form đơn xin việc chuyên biệt dành cho dân lập trình.

  Tổng hợp một số mẫu CV đẹp mắt dành cho lập trình viên

  Top 5 website giúp thiết kế CV chuẩn format, đủ nội dung

Viết cv online thu hút nhà tuyển dụng

Khi bắt tay vào viết CV onl thì bạn nên chú ý điền đầy đủ thông tin cần điền bên phần thông tin cá nhân như hình ảnh, số điện thoại, mail… Tiếp theo mới bắt đầu điền các thông tin về kinh nghiệm làm việc có liên quan đến vị trí đang muốn ứng tuyển. Tất cả bạn chỉ cần điền theo form có sẵn, thêm bớt các thông tin sao cho CV của bạn trở nên thật hoàn hảo nhé! Ngoài ra nếu bạn muốn ver cv bằng tiếng anh thì hãy chọn từ đầu nhé.

Ngoài ra bạn cũng có thể điều chỉnh font chữ, size trên đó, vì vây hãy chắc chắn rằng font chữ của bạn đồng nhất. Bạn cũng nên kiểm tra lại lỗi chính tả trong CV online của bạn, đừng liệt kê quá nhiều sở thích cá nhân vì nhà tuyển dụng sẽ không quan tâm đến những điều đó và nếu liệt ra ra quá nhiều sở thích không cần thiết thì sẽ làm CV của bạn rối nùi.

Một mẹo nhỏ nữa để làm cv online của bạn được nhà tuyển dụng lựa chọn là bạn nên trung thực, đừng vì quá tham mà liệt kê những kỹ năng cũng như kiến thức bạn chưa bao giờ làm qua. Đúng là 1 nhân viên giỏi, biết nhiều thứ thì ai cũng thích nhưng nổ quá cái gì cũng biết từ sale đến design, marketing, lập trình cái nào cũng biết thì sẽ được đặt dấu chấm hỏi! Nguy hiểm hơn là nhà tuyển dụng còn nghĩ bạn viết dối chỉ để được phỏng vấn nên sẽ loại bạn ngay từ vòng lọc CV Online.

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

Thêm một điều nên nhớ nữa là bạn không nên dùng 1 CV cho tất cả ngành nghề, mỗi ngành khác nhau sẽ cần những kinh nghiệm công việc khác nhau. Ví dụ như mẫu CV dành cho dân lập trình viên rất đặc thù vì cần phải có thiết kế phù hợp để show ra được những đường link dự án sao cho thật bắt mắt, điều đó khác hẳn so với những CV của dân sale hay marketing….

Nhìn chung, việc viết cv không còn là nỗi ám ảnh khi đi xin việc nữa vì hiện nay ứng viên đã được hỗ trợ rất nhiều từ các template CV online của các trang web tìm việc. Việc duy nhất các ứng viên cần quan tâm đó là chọn cho mình 1 mẫu CV phù hợp với ngành và trang bị kiến thức thật vững vàng trước khi đi gặp nhà tuyển dụng.

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

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

6 ví dụ để bạn yêu luôn observable

6-vi-du-de-ban-yeu-luon-observable
Bài viết được sự cho phép của tác giả Lưu Bình An

Thêm những lý do để dụ dỗ bạn xài Observable

Observable mình dịch ra tiếng việt thế này cho bạn dễ hình dung. Một khi bạn bật chế độ observable với một đứa con gái nào đó, là bạn đang trong giai đoạn bị nó ám ảnh, nhất cử nhất động của nó bạn điều để ý, nó hắc xì bạn cũng biết, một tuần nó mặc mấy bộ đồ bạn cũng biết. Chỉ cần nghe tiếng bước chân là bạn biết được hôm nay nó mang đôi dép gì (mức độ này hơi kinh khủng lắm rồi) là bạn có những phản xạ vô điều kiện bộc phát nơi cửa miệng “Chiều nay trời mưa nhe em, mang dép lào đi cho chuẩn”. Phản xạ này là gọi là subscription

Rồi quay lại với vấn đề kỹ thuật, bài này không giải thích rõ Observable pattern, các khái niệm chính của nó, nếu muốn bạn đọc lại bài này trước đây có viết rồi, như cái tựa bài viết nó spoil hết cái nội dung rồi “Ví dụ để thấy tại sao chúng ta nên bật chế độ Observable với một em gái nào đó”

Thần chú mình muốn bạn thuộc lầu

Lập trình Reactive là làm việc với luồng dữ liệu bất đồng bộ

Lại phải giải thích câu này chút, Nếu những gì diễn ra trên ứng dụng đang xảy ra một cách bất đồng bộ, khả năng rất cao là Observable sẽ giúp ích cho cuộc sống của anh em chúng ta bớt khổ hơn.

Có nhiều cách làm và thư viện handle vụ luồng dữ liệu bất đồng bộ này, tuy nhiên, Observable có gì mà cool, sắp được chuẩn hóa và đưa vào ECMAScript. Thư viện RxJS đang được sử dụng rộng rãi và quá ngon rồi.

Rồi vô luôn ví dụ nhe

Handle các event bằng Observable

Chúng ta có 1 button, khi button này click tạo ra một chuỗi ngẫu nhiên. Viết bằng cả 2 cách javascript thuần, và sử dụng RxJS

const button = document.querySelector('button');
const output = document.querySelector('output');

button.addEventListener('click', e => {
    output.textContent = Math.random().toString(36).slice(2);
})

Bằng RxJS nè

const button = document.querySelector('button');
const output = document.querySelector('output');

Rx.Observable
    .fromEvent(button, 'click')
    .subscribe(() => {
        output.textContent = Math.random().toString(36).slice(3);
    })

Nó dài hơn khi viết javascript thuần mà man 😂. Chi mà phức tạp vậy? Đúng luôn, nhưng giờ thêm yêu cầu này vào thì sao: Ở mỗi lần click đến bội số của 3 ( 3,6,9,12,…) thì mới random một string mới

Rx.Observable
    .fromEvent(button, 'click')
    .bufferCount(3) // một dòng duy nhất
    .subscribe(() => {
        output.textContent = Math.random().toString(36).slice(3);
    })

Vậy bạn viết JS thôi thì sao, khỏi nói cũng biết nó sẽ dài dòng hơn.

Operator, operator

Trong ví dụ trên, .bufferCount *đã cho thấy sức mạnh vượt trội** so với cách thông thường. Có thể nói thế này, chúng ta xài Observable này là vì những gì chúng ta làm được bằng operator. Trong thư viện RxJS nó cả tá Operator tha hồ mà chơi.

Một ví dụ khác, cũng là vụ random string ở trên, mà giờ chỉ muốn random khi nó là một cú triple click (một phát 3 nháy, không phải double click nhoa)

const click$ = Rx.Observable.fromEvent(button, 'click');

click$.Observable
    .bufferWhen(() => {
        click$.delay(400);
        // kkhoảng thời gian của một cú 3 click
    })
    .filter(events => events.length >= 3)
    .subscribe(() => {
        output.textContent = Math.random().toString(36).slice(3);
    })

DỊch ra ngôn ngữ con người nó sẽ như thế này, trong khoảng thời gian là 400ms, trong đám event được emit (tụi này được đưa vào mảng events), nếu mảng này lớn hơn hoặc bằng 3, thực hiện đống việc đã đăng ký bên dưới subscribe

Bạn đã bắt đầu yêu Observable chưa? Mình đã khoái khoái rồi đó.

Ai có thể là Observable

Đơn giản, bất kể già trẻ lớn bé, trai gái, nếu RxJS có hàm ( khi nãy là .fromEvent) thì chúng ta có thể biến nó thành đối tượng bị theo dõi liên tục.

Observable cho các HTTP request

Một sức mạnh siêu nhiên khác của RxJS: xử lý mấy em HTTP request rất mượt mà

Ví dụ, fetching một danh sách album và render.

const albumsApiUrl = 'https://jsonplaceholder.typicode.com/albums';

Rx.Observable
    .ajax(albumsApiUrl)
    .subscribe(
        res => console.log(res),
        err => console.log(err)
    )

Trộn chung với ví dụ ở trên, chúng ta làm cái tính năng awsome sau, click là có danh sách album ngẫu nhiên

Rx.Observable
    .fromEvent(button, 'click')
    .flatMap(getAlbums)
    .subscribe(
        render,
        err => console.error(err)
    )

function getAlbums() {
    const userId = Math.round(Math.random() * 10);
    return Rx.Observable.ajax(
        `https://jsonplaceholder.typicode.com/albums?userId=${userId}`
        )
}

Ví dụ trên có sử dụng operator flatMap, 1 trong những operator siêu kinh điển của RxJS, cho phép merge 2 mảng kiểu Observable thành 1

Nếu chúng ta click liên tục trong thời gian ngắn, là có vấn đề, re-render nhiều lần, chúng ta cũng ko xác định được request nào được resolve cuối cùng. Cụ thể là thế này, có thể thằng xuất phát trước lại về đích sau cùng, chuyện của network ai mà biết được thời điểm đó nó download film gì làm chậm mạng, thằng request sau có khi lại về đích trước, như vậy thì dùng cục response lúc nào để render, mình muốn response của thằng request cuối cùng.

Bạn muốn, trong công cuộc tán gái, đứa nào ở lại đến giây phút cuối cùng là đứa chiến thắng, bạn sẽ dẹp luôn những đứa nào thả thính trước đó? Ví von như vậy cũng chưa chuẩn, phải là đứa nào đến sau cùng thì dữ lại, dẹp mẹ tụi tới trước (thế này thì bất công vl mấy bạn)

RxJS làm được chuyện đó không? Có chứ, mọi thứ đã có operator, chuyển qua dùng switchMap, sẽ chỉ có response cuối cùng được render, mấy request trước đó sẽ bị cancel hết

Rx.Observable
    .fromEvent(button, 'click')
    .switchMap(getAlbums)
    .subscribe(
        render,
        err => console.error(err)
    )

Kết hợp các Observable

Một use case khác mà chúng ta gặp hoài. Chức năng filter hoạt động như sau: cho tụi user nhập vào user id bằng <input />, và chọn thể loại âm nhạc nó muốn bằng <select />. Điều quan trọng là chỉ tạo request mới khi cả 2 giá trị trong đó điều có dữ liệu, và re-render khi một trong 2 giá trị này bị thay đổi.

Tạo Observable trước nhé

const id$ = Rx.Observable
    .fromEvent(input, 'input')
    .map(e => e.target.value)

const resource$ = Rx.Observable
    .fromEvent(select, 'change')
    .map(e => e.target.value)

Chúng ta phải hợp thể 2 thằng trên vào một, để khi một trong 2 thằng có thay đổi chúng ta lấy được giá trị sau cùng của cả 2. mọi thứ đã có operator, nhiều lắm, ở đây dùng combineLatest

Rx.Observable
    .combineLatest(id$, resource$)
    .switchMap(getResource)
    .subscribe(render)

Kết

Bạn đã thấy sử dụng Observable thú vị dường nào chưa? Nếu câu trả lời là “Có ❤️, trọn đời yêu em”, bạn hãy nhào vô document của nó để nghiên cứu chuyên sâu hơn.

Nếu câu trả lời là “No 💩, anh éo care mấy đứa ạ”. Thì bạn cũng nên bớt bớt đối xử tệ với nó đi, vì trong tương lai JS sẽ đưa nào vào như một object chính thức luôn, không chạy đằng trời được đâu các bạn ạ.

Hy vọng anh em hôm nay đã học thêm được cái gì đó thú vị, hẹn gặp lại anh em vào một viết thú vị khác.

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

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

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

Dùng Px, Em hay Rem để viết media query

Dùng Px, Em hay Rem để viết media query
Bài viết được sự cho phép của tác giả Lưu Bình An
Khi viết media query, bạn có bao giờ thắc mắc nên dùng đơn vị nào: px, em hay rem? Các bạn đọc bài này mình mặc định bạn đã phân biệt được sự khác nhau giữa em và rem

Setup để thử nghiệm

Chúng ta sẽ dùng 3 div tô 3 màu khác nhau để thấy được kết quả dễ dàng

.pixel { background: red; }
.em { background: green; }
.rem { background: blue; }

Chúng ta viết query min-width trên 3 element này, thay đổi opacity để thấy được khi nào css này được áp dụng

.pixel {
	background: red;
	@media (min-width: 400px) {
		opacity: .5
	}
}

Chúng ta sẽ đặt font-size cho html là 16px = 1em = 1rem. Như vậy 400px = 25em = 25rem

.em {
  background: green;  
  @media (min-width: 25em) {
    opacity: 0.5
  }
}

.rem {
  background: blue;  
  @media (min-width: 25rem) {
    opacity: 0.5
  }
}

Tất cả đều được trigger ở chính xác kích thước 400px

Dùng Px, Em hay Rem để viết media query

  Tối ưu hóa việc thực thi query trong MYSQL
  Những gợi ý sử dụng jQuery bạn nên biết

Thay đổi font size ở HTML

Trường hợp phổ biến nhất chúng ta hay gặp là thay đổi font-size trên HTML

html {
	font-size: 200%;
}

Khi thay đổi font-size lên 200%, nghĩa là 1em = 1rem = 32px. Nếu sự thay đổi font-size này tác động lên em và rem, chúng ta sẽ thấy 2 element bên dưới trigger ở 800px

Kết quả trên Chrome, Firefox và IE11, cả 3 thằng đều trigger ở 400px

Dùng Px, Em hay Rem để viết media query

Nếu chạy đúng, em và rem không nên bị ảnh hưởng bởi thay đổi font-size trên HTML, nó chỉ được phụ thuộc vào font-size mặc định của trình duyệt.

Tuy nhiên, trên Safari lại cho kết quả không như mong đợi, nó trigger ở 800px

Dùng Px, Em hay Rem để viết media query

Với kết quả này chúng ta có thể bỏ qua việc sử dụng rem với media query vì nó ko đảm bảo chạy đúng trên mọi trình duyệt.

Tuy nhiên, các thí nghiệm bên dưới chúng ta vẫn đưa rem vào cho vui!

User gọi Zoom In

Đây cũng là tình huống thường thấy, chữ quá nhỏ, user có xu hướng zoom to lên xem.

Nguyên nhân chính có đơn vị em là vì các trình duyệt cũ không thể update giá trị pixel khi user gọi zoom

Trên Chrome, Firefox và IE, pxemrem xảy ra cùng lúc

Dùng Px, Em hay Rem để viết media query

Và đương nhiên Safari tiếp tục không giống ai

Dùng Px, Em hay Rem để viết media query

Điều này có nghĩa là, đơn vị pixel không đúng trên mọi browser, bạn nên dừng sử dụng pixel trong câu media query, trừ khi bạn thuộc kiểu sống bất chấp sự tồn tại của safari

User thay đổi giá trị font mặc định của trình duyệt

Rất nhiều developer tin rằng user chả đứa nào thay đổi font size mặc định của trình duyệt, tìm cái thiết đặt này trong trình duyệt đã đủ khó khăn làm user nản chí

Tuy nhiên đó là niềm tin không có căn cứ, không có dữ liệu chứng minh được, user vẫn có thể google tìm cách thay đổi font size mặc định của trình duyệt, đặc biệt các thanh niên bị cận như mình.

Nếu chưa biết cách thay đổi font-size mặc định của trình duyệt, mình chỉ cho

Chrome: Settings > Show advanced settings > Web content Firefox: preferences > content > fonts and colors IE: page > text-size

Safari thì mình chưa biết thay đổi font-size của nó bằng cách nào.

Dùng Px, Em hay Rem để viết media query

Như có thể thấy, câu query dùng px trigger sớm hơn em và rem

Cái này không phải là bug, vì px là đơn vị chính xác đến từng pixel!!! Nó chỉ cần biết kích thước độ rộng màn hình, không liên quan họ hàng gì tới font-size

Ngược lại 2 đơn vị rem và em phụ thuộc hoàn toàn vào font-size của trình duyệt

Chúng ta phải nói lời chia tay với pixel khi viết media query

Ví dụ bạn setup để màn hình dưới 600px có một cột, ngược lại có 2 cột. Mọi thứ đẹp nếu font size là 16px, tuy nhiên nếu user đổi font size thành 20px và xem ở màn hình 650px. Đơn vị rem và em sẽ cho ra giao diện 1 cột, trong khi pixel vẫn lì lợm 2 cột bất chấp cái font chữ giờ đã to đùng.

Kết luận

Đơn vị cho kết quả chấp nhận được ở mọi tình huống là em

Nếu từng thắc mắc khi đang dùng một thư viện nào đó, như bootstrap, tại sao nó lại dùng đơn vị em trong câu media query, thì giờ bạn đã có câu trả lời rồi đó.

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

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

Xem thêm các IT Jobs for Developer hấp dẫn tại TopDev

Những ứng dụng tuyệt vời của Renderless component trong Vue

Những ứng dụng tuyệt vời của Renderless component trong Vue
Bài viết được sự cho phép của tác giả Lưu Bình An
Để tái sử dụng component trong Vue mà không biết tới slot thì quá thiếu sót. Một vài ví dụ để bạn sử dụng slot nhiều hơn.
  Tạo web siêu dễ với VuePress và Github Pages
  Viết Unit Test cho Vue component cho người mới bắt đầu

Slot

Slot trong vue là dạng “đặt gạch” trong component, sau này khi sử dụng ta có thể đưa nội dung khác vào những vị trí đã đặt gạch

Vue không chỉ có thể đặt một mà đặt nhiều gạch, số lượng tùy thích, viên gạch đó được Vue gọi tên là slot

<!-- mother.vue --> Mẹ đặt gạch 2 chỗ header và body cho con nha
<template>
  <div class="card">
    <div class="card-header">
      <slot name="header"></slot>
    </div>
    <div class="card-body">
      <slot name="body"></slot>
    </div>
  </div>
</template>
<!-- con.vue: Cho con dùng 2 chỗ header và body bằng nội dung mới nhé-->
<mother>
	<template #header>
	  <h1>Special Features</h1>
	</template>
	<template #body>
		<div>
		    <h5>Fish and Chips</h5>
		    <p>Super delicious tbh.</p>
		</div>
	</template>
</mother>

Đây là những viên gạch có đặt tên <slot name="header"/>, có một viên gạch không cần đặt tên, chỉ cần <slot />, khi đó component ném gạch sẽ được viết

<mother>
  Toàn bộ phần này nằm trong slot không đặt tên
</mother>

Slot scope

Đề truyền dữ liệu từ mẹ sang con, chúng ta bind dữ liệu muốn truyền qua slot <slot :ten-bien="du-lieu"/>

<!-- mother.vue -->
<template>
  <div class="card">
    <div class="card-header">
      <slot name="header" :close="close"></slot>
    </div>
    <div class="card-body">
      <slot name="body"></slot>
    </div>
  </div>
</template>

Component con sẽ nhận dữ liệu thông qua từ khóa slot-scope

<!-- con.vue-->
<mother>
	<template #header slot-scope="{close}">
		<h1>{{ close ? ‘Closed’ : ‘Open’ }}</h1>
	</template>
	<template #body>
		<div slot="body">
		  <h5>Fish and Chips</h5>
		  <p>Super delicious tbh.</p>
		</div>
	</template>
</mother>

Sử dụng làm modal

Lấy structure của bootstrap nhé, chúng ta sẽ cho Modal component có 3 chỗ có thể thay đổi là

  • <slot name="header" />
  • <slot name="body" />
  • <slot name="footer" />
<!-- my-modal.vue -->
<template>
<div class="modal" tabindex="-1" role="dialog">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <slot name="header"></slot>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">×</span>
        </button>
      </div>
      <div class="modal-body">
        <slot name="body"></slot>
      </div>
      <div class="modal-footer">
        <slot name="footer"></slot>
      </div>
    </div>
  </div>
</div>
</template>

Với 3 cục gạch đã đặt sẵn trong my-modal.vue,

<template>
  <my-modal>
    <!-- kiểu viết tắt của `v-slot` là # -->
    <template #header>
      <h5>Awesome Interruption!</h5>
    </template>
    <template #body>
      <p>Say something....</p>
    </template>
    <template #footer>
      <em>Ahihi</em>
    </template>
  </my-modal>
</template>

Bổ sung thêm một tính năng năng nữa cho component <my-modal/>, mặc định khi click nút close, nó sẽ gọi đến hàm close bên trong component <my-modal/>, chúng ta dùng scope slot để thằng con có thể truyền vào một function khác, đè lên function nhận được (tức không gọi hàm closeModal bên trong <my-modal/>)

<!-- my-modal.vue -->
<template>
<div class="modal" tabindex="-1" role="dialog">
	//...
	<div class="modal-footer">
	  <slot name="footer" :closeModal="closeModal"></slot>
	</div>
	//...
</div>
</template>

<script>
export default {
  //...
  methods: {
	closeModal () {	}
  }
}
</script>

Chúng ta có thể truyền hàm closeModal khác

<template #footer="{closeModal}">
	<button @click="closeModal">
		I'm here
	</button>
</template>

Composing Component (siêu nhân hợp thể)

Sự kết hợp của nhiều component thành một component mới, dữ dội hơn, như siêu nhân GAO, được gọi là hợp thể component. Từ khoa học của nó là Composing Components

Tại sao cần hợp thể?

Component được sinh ra là để chúng ta nhai đi nhai lại

<!-- BaseButton.vue -->
<template>
  <button class="nice-button" type="button">
    {{ text }}
  </button>
</template>

<script>
export default {
  props: ['text']
}
</script>

Nhu cầu thêm mắm, bớt muối cho một món phải nhai đi nhai lại là có. Giả dụ ta đã có sẵn một component BaseIcon để làm chuyện hiển thị icon, giờ cái Button cùng muốn thêm chút icon cho đời tươi mới, chúng ta xào chung hai món lại để nhai

<template>
  <button class="nice-button" type="button">
    <BaseIcon v-if="leftIcon" :icon="leftIcon"/>
    {{ text }}
    <BaseIcon v-if="rightIcon" :icon="rightIcon"/>
  </button>
</template>

<script>
export default {
  props: ['text', 'leftIcon', 'rightIcon']
}
</script>

Trong đó chúng ta đã thêm hai điều kiện để đặt icon nằm bên trái hay bên phải. Component Button bây giờ cũng được thêm 2 prop rightIconleftIcon.

Thí dụ như có thêm yêu cầu đưa cái spinner vào trong button, khi nào đang loading thì hiện cái spinner này

<template>
  <button class="nice-button" type="button">
    <BaseSpinner v-if="isLoading"/>
    <template v-else>
      <BaseIcon v-if="leftIcon" :icon="leftIcon"/>
      {{ text }}
      <BaseIcon v-if="rightIcon" :icon="rightIcon"/>
    </template>
  </button>
</template>

Chỉ mới thêm chút đường sữa thôi, mà món ăn sắp thành cháo heo thập cẩm khó nuốt. Với nhiều gia vị được yêu cầu bỏ vào của bọn khách hàng không biết gì về nấu nướng. Món ngon bây giờ thành đặc sản mà đứa nào đó muốn nấu tiếp, sửa đổi do quá mặn, thì cũng bất lực vì không biết đã thêm quá nhiều muối hay nhiều nước mắm.

Một cách nấu khác với slot

Trong cuốn bí kíp 100 cách nấu ngon của Vue.js, nó cho chúng ta cách làm khác gọi là slot

<template>
  <button class="nice-button" type="button">
    <slot/>
  </button>
</template>

Đây là kiểu món tao đã nấu xong, nếu mày muốn bỏ thêm bất cứ gì đó, dùng món này tao đã nấu xong như một nguyên liệu cho món mới, chứ tao ko sửa lại món của tao.

<BaseButton>
  Submit
  <BaseIcon icon="arrow-right"/>
</BaseButton>

Việc này tạo ra một tranh cãi trong giới đầu bếp, nếu tao phải phục vụ món ăn đó cho một trăm thực khách, tức là tao phải lặp lại việc order 100 gia vị Button về rồi tự nấu thêm 100 lần nữa, vi phạm nguyên tắc nghề nghiệp DRY (DON’T REPEAT YOURSELF) của tao. Đúng là vi phạm nguyên tắc nghề, nhưng nó lại đảm bảo KISS (Keep it simple stupid – NGU NHẤT CÓ THỂ)

<template>
  <BaseButton @click="sendForm">
    <BaseSpinner v-if="isLoading"/>
    <template v-else>
      Submit
      <BaseIcon icon="arrow-right"/>
    </template>
  </BaseButton>
</template>

Renderless Component (người vô hình chỉ mang logic)

Một component trong Vue có thể không render bất cứ gì cả, nếu chỉ đơn giản là chứa các function, thực hiện logic tính toán. Nó giống như cái ổ điện, nó chỉ biết làm một chuyện là cấp điện cho chui cắm, còn cái chui đó nối tới bóng đèn, máy tính, tủ lạnh, máy quạt là chuyện của người cắm điện.

<template>
	<transition name="fade" v-bind="$attrs" v-on="$listeners">
		<slot></slot>
	</transition>
</template>

<style>
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s;
}
.fade-enter, .fade-leave-to {
  opacity: 0;
}
</style>

Một component để làm transition như trên không render html, không quan tâm cái nó hiển thị là gì. Nó chỉ bổ sung hiệu ứng fade cho component.

Có thể viết nó ở dạng này, truyền thêm ít dữ liệu cho đứa con

Vue.component('renderless-component-example', {
	render() {
		return this.$scopedSlots.default({
			exampleProp: 'vuilaptrinh.com'
		})
	}
})

Tại sao dùng Renderless component mà không dùng mixin hay directive?

Để tái sử dụng code trong Vue, ngoài renderless component ra còn có thể dùng Mixin hoặc 1 custom Directive. Cả 3 cách đều có thể dùng thay thế cho nhau được, vấn đề là mức độ tường minh của 3 thằng khác nhau, thằng directive là kém tường minh nhất, với mixin và renderless component chúng ta import độc lập trên từng component muốn xài, xem như bằng nhau. Mixin thì bị vấn đề, nếu khai báo một số state, hoặc hàm bên trong mixin, sau đó trộn chung với 1 component, không rõ ràng trực quan như là dùng một renderless component với prop

Ứng dụng renderless component làm ổ cắm mạng cấp dữ liệu internet

Chúng ta thường xuyên làm việc này, tạo một network request lúc component mounted() để lấy dữ liệu, chúng ta tạo ra một component chuyên làm nhiệm vụ này

// src/components/DataList.js
import axios from 'axios'

export default {
	props: {
		baseUrl: {
			type: String,
			default: 'https://jsonplaceholder.typicode.com'
		},
		endpoint: {
			type: String,
			required: true
		},
		// dùng để giới hạn kết quả query
		filter: {
			type: Object
		}
	},
	data() {
		return {
			api: axios.create({ baseURL: this.baseUrl }),
			data: null,
			error: null,
			loading: false,
		}
	},
	watch: {
		// load dữ liệu từ endpoint trong lần render đầu tiên
		// và khi giá trị filter thay đổi
		filter: {
			immediate: true,
			handler: 'load'
		}
	},
	methods: {
		// xử lý tất cả type: post, update, delete, get, put bằng một hàm duy nhất
		async query(type, ...params) {
			// tránh việc gọi load liên tục
			if (this.loading) return;

			this.loading = true;

			try	{
				const response = await this.api[type](...params);
				this.data = response.data;
				this.error = null;
				this.$emit('success', response);
			} catch (error) {
				this.data = null;
				this.error = error.response;
				this.$emit('error', error);
			}
			this.loading = false;
		},
		load() {
			return this.query('get', this.endpoint, { params: this.filter })
		}
	},
	render() {
		// đưa toàn bộ dữ liệu và phương thức xuống con thông qua slot scope
		return this.$scopedSlots.default({
			data: this.data,
			error: this.error,
			load: this.load,
			loading: this.loading
		})
	}
}

Renderless component <DataList/> sẽ làm nhiệm vụ fetch dữ liệu từ một API, endpoint được cung cấp qua prop, sau đó nó sẽ quăng kết quả, lỗi, trạng thái hiện tại về cho component con

<data-list endpoint="posts">
	<div slot-scope="{ data: posts, error, laoding }">
		<span v-if="loading">Loading...</span>
		<span v-else-if="error">Error while fetching data!</span>
		<ul v-else>
			<li v-for="post in posts" :key="post.id">
				<h3>{{ post.title }}</h3>
				<p>{{ post.body }}</p>
			</li>
		</ul>
	</div>
<data-list>

Thêm phần phân trang, chúng ta dùng giá trị filter

<data-list endpoint="posts" :filter="{ page }">
	<div slot-scope="{ data: posts, error, laoding }">
		<span v-if="loading">Loading...</span>
		<span v-else-if="error">Error while fetching data!</span>
		<ul v-else>
			<li v-for="post in posts" :key="post.id">
				<h3>{{ post.title }}</h3>
				<p>{{ post.body }}</p>
			</li>
		</ul>
		<button @click="page = 1">1</button>
    <button @click="page = 2">2</button>
    <button @click="page = 3">3</button>
	</div>
<data-list>

Bởi vì đã setup watch trên giá trị filter, nên khi thay đổi giá trị của page, nó sẽ gọi lại hàm load()

Xong phần Rờ trong CRUD, giờ đến Create-Update-Delete

Chúng ta cần tách phần code ở trên ra thành một mixin để sử dụng vào component detail. Chúng ta sẽ đưa nó vào một mixin là query.js

// src/components/mixins/query.js
import axios from 'axios';

export default {
  props: {
    baseUrl: {
      type: String,
      // The JSONPlaceholder API is a fake API
      // basically a Lorem Ipsum JSON API.
      default: `https://jsonplaceholder.typicode.com`,
    },
    endpoint: {
      type: String,
      required: true,
    },
  },
  data() {
    return {
      // Create a new axios instance.
      // See: https://github.com/axios/axios#creating-an-instance
      api: axios.create({ baseURL: this.baseUrl }),
      data: null,
      error: null,
      loading: false,
    };
  },
  methods: {
    // The `query` method will handle
    // different query types for us.
    async query(type, ...params) {
      // If we're currently loading content
      // we don't submit an additional request.
      if (this.loading) return;

      this.loading = true;
      try {
        const response = await this.api[type](...params);
        this.data = response.data;
        this.error = null;
        this.$emit(`success`, response);
      } catch (error) {
        this.data = null;
        this.error = error.response;
        this.$emit(`error`, error);
      }
      this.loading = false;
    },
  },
};

Với component để thêm-xóa-sửa

// src/components/DataModel.js
import queryMixin from './mixins/query'

export default {
	mixins: [queryMixin],
	props: {
		entity: {
			type: Object,
		},
		id: {
			type: [Number, String]
		}
	},
	data() {
		return {
			data: this.entity || null,
		}
	},
	create() {
		// nếu có id và chưa có dữ liệu, chúng ta gọi fetch dữ liệu
		if (this.id && !this.data) this.find();
	},
	methods: {
		create(data) {
			return this.query('post', this.endpoint, data)
		},
		destroy() {
			return this.query('delete', `${this.endpoint}/${this.id}`)
		},
		find() {
      return this.query('get', `${this.endpoint}/${this.id}`);
    },
    update(data) {
      return this.query('patch', `${this.endpoint}/${this.id}`, data);
    },
	},
	render() {
		return this.$scopedSlots.default({
			create: this.create,
			data: this.data,
			destroy: this.destroy,
			loading: this.loading,
			update: this.update
		})
	}
}

Create

<data-model endpoint="posts">
	<div slot-scope="{ data: post, loading, create }"></div>
	<span v-if="loading">Loading...</span>
  <template v-if="post">
    <h3>{{ post.title }}</h3>
    <p>{{ post.body }}</p>
  </template>
  <form @submit.prevent="create(newPost)">
  	<label>
      Title: <input v-model="newPost.title">
    </label>
    <label>
      Body: <input v-model="newPost.body">
    </label>
    <button :disabled="loading">
      <template v-if="loading">Loading...</template>
      <template v-else>Create</template>
    </button>
  </form>
</data-model>

Với component để Create, chúng ta không truyền dữ liệu và id, vì thế nó không gọi API để lấy dữ liệu, nếu sau khi tạo, chúng ta sẽ nhận giá trị post và id.

Cập nhập, giống hệt với tạo ở trên, có điều có thêm id

<data-model endpoint="posts" :id="1">
  <div slot-scope="{ data: post, loading, update }">
    <span v-if="loading">Loading...</span>
    <template v-if="post">
      <h3>{{ post.title }}</h3>
      <p>{{ post.body }}</p>
    </template>

    <form @submit.prevent="update(post);">
      <label>
        Title: <input v-model="post.title">
      </label>
      <label>
        Body: <input v-model="post.body">
      </label>
      <button :disabled="loading">
        <template v-if="loading">Loading...</template>
        <template v-else>Update</template>
      </button>
    </form>
  </div>
</data-model>

Delete

<data-model endpoint="posts" :id="1" @success="deleted = true">
  <div slot-scope="{ delete }">
    <p v-if="deleted">
      The post was successfully deleted.
    </p>
    <button :disabled="loading">
      <template v-if="loading">Loading...</template>
      <template v-else>Delete</template>
    </button>
  </div>
</data-model>

Tài liệu tham khảo

Building Renderless Components to Handle CRUD Operations in Vue.js

Vue.js Pattern for Async Requests: Using Renderless Components

Renderless Components in Vue.js

Composing Components in Vue.js

Using Slots In Vue.js

Creating Reusable Transitions in Vue

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

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

Xem thêm các việc làm VueJS lương cao hấp dẫn tại TopDev

“Sống sót” qua những áp lực trong tuyển dụng IT – lập trình, có dễ không?

ngành lập trình

Phải chăng bạn từng nghe luyên thuyên trong những cuộc trò chuyện của người lớn, những cuộc thoại của đám bạn rằng ngành lập trình là một ngành dễ thở, công việc thì thú vị, không những ngồi máy lạnh mà lại còn được hưởng mức lương cao. 

Liệu lối nghĩ mặc định ấy có đúng không và sự thật thế nào? Bạn có biết rằng ngành IT cũng giống như những ngành khác, đều có hai mặt của nó, việc phải thu nạp một lượng kiến thức khủng, gặp đủ thứ áp lực khác nhau là những mặt tối mà chỉ được chính dân lập trình giấu nhẹm đằng sau bề nổi hào nhoáng kia mà thôi.

Hôm nay, TopDev sẽ bật mí cho các bạn vô vàn những áp lực xoay quanh ngành lập trình IT khi đã quyết định dấn thân theo đuổi nó. Tất nhiên, bài viết sẽ chia sẻ thêm những cách thức giúp thích ứng và sống sót khi những áp lực bủa vây.

Áp lực từ các mối quan hệ: Sếp và đồng nghiệp

Không phải ai xa lạ, áp lực lớn nhất mà bạn phải đối mặt chính là từ sếp của bạn. Điều này khá dễ hiểu vì sếp là người trực tiếp phân bổ các đầu công việc mà bạn phải thực hiện, quản lý đồng thời hỗ trợ bạn tự đánh giá hiệu suất làm việc của bản thân.

Nếu không may mắn gặp phải một người sếp khó tính, những áp lực bạn phải đối mặt có thể là gì? 

  • Task quá khó nằm ngoài năng lực chuyên môn 
  • Buộc làm thêm ngoài giờ để đảm bảo tiến độ công việc, kết quả cho ra hoàn hảo nhất có thể
  • Làm khó làm dễ nhân viên, đánh giá thấp việc xem xét tăng lương làm giảm cơ hội cho việc phát triển sự nghiệp

Chính vì thế, điều bạn cần làm trường hợp này là cho sếp một khoảng riêng, giao tiếp trao đổi ý kiến và quan trọng là nắm bắt tâm lý và thấu hiểu được sếp của bạn. Sếp của bạn có rất nhiều việc cần giải quyết và đôi khi việc bộc phát những cơn giận chỉ là cách thúc đẩy bạn và team làm việc hiệu quả hơn. Vì thế đừng giận và đừng áp lực về công việc. 

Ngoài ra, khi giao tiếp, bạn nên cẩn trọng với từng phát ngôn của mình. Nếu có những phát sinh hay các tồn đọng tạo ra nguy cơ dẫn đến sự tiêu cực, bạn đừng vội đi sâu vào vấn đề chuyên môn hay kỹ thuật. Thay vào đó, hãy khai thác những khía cạnh mà sếp quan tâm đồng thời cũng là cách giúp tiếp cận cơn giận từ sếp.

  Kỹ năng giao tiếp? Làm thế nào để cải thiện giao tiếp hiệu quả?

ngành lập trình

  • Diễn tiến thực hiện dự án như thế nào?
  • Làm sao để cải thiện năng suất làm việc hiệu quả?
  • Sếp có lời khuyên nào cho em trong việc giải quyết vấn đề này không?

Việc thấu hiểu sếp còn phụ thuộc vào nhiều yếu tố, vì nếu đối với một người sếp không tốt, lúc nào cũng kiếm chuyện với nhân viên thậm chí không tuân thủ các quy định thì việc bạn nhảy việc, bắt đầu sự nghiệp  tại một công ty khác là điều sớm muộn.

Đồng nghiệp là người sẽ tiếp xúc, làm việc với bạn nhiều hơn là sếp. Vì thế, những áp lục xảy ra có liên quan đến đồng nghiệp cũng khiến bạn đau đầu đó.

Bạn có thể sẽ gặp phải những người đồng nghiệp khoác lác về năng lực hoặc quá tự kiêu về bản thân có thể khiến bạn cảm thấy phiền phức. Khi làm việc nhóm đòi hỏi sự bàn luận về dự án và trình bày những ý kiến đóng góp, đồng nghiệp của bạn tỏ thái độ thiếu hợp tác; đùn đẩy trách nhiệm cho người khác. Hoặc khi chung team với những đồng nghiệp giỏi khiến bạn cảm thấy tự ti và thua kém về nhiều mặt.

“Mỗi người một vẻ” nên có đồng nghiệp này, đồng nghiệp khác. Ai cũng có điểm mạnh điểm yếu riêng. Ví dụ một số người chưa thật sự giỏi về lập trình IT, nhưng bù lại họ có chí cầu tiến và khả năng tiếp nhận kiến thức một cách nhanh chóng. Điều bạn cần nhớ và thực hiện là hãy học cái hay của những người đồng nghiệp giỏi.

Bộc lộ sự ngờ vực về chính bản thân

Có lẽ nỗi ám ảnh về chuyên đề nhập môn lập trình hay các bài giảng về thuật toán và cấu trúc dữ liệu có thể bạn sẽ không thể nào quên. Khoảng thời gian đầu đã trôi qua nhưng khi nhìn nhận lại, những rào cản ấy đã phần nào khiến bạn nhận ra sự không phù hợp với đặc thù ngành hoặc đơn giản khiến bạn nghi ngờ về khả năng và chính sự lựa chọn của bản thân mình. Sai ngành thật à? Tồn thời gian học làm chi vậy? Bao nhiêu câu hỏi sẽ được đặt ra và chúng dường như quay cuồng xung quanh bạn.

Thời học C++, nhiều bạn phải điên cuồng làm những bài tập, đôi khi không tha thiết mấy những vẫn cố mà cày nó. Vấn đề nằm ở chỗ việc bạn có nhìn nhận được hiện thực chung hay không thôi. 

ngành lập trình

Một lập trình viên không tự sinh ra được, cái gì cũng phải có quá trình khổ luyện. Tất nhiên trong quá trình ấy phải có sự cộng hưởng giữa nhiều yếu tố về năng lực, tiềm năng, sự cố gắng và cả sự may mắn. Vì vậy, khi gặp những khó khăn trong ngành học hay công việc, dù nó là gì thì nó cũng chỉ là một phần, một khía cạnh nhỏ trong cuộc sống này mà thôi. Điều bạn cần nhớ là đừng bao giờ nghĩ mình không có khả năng, mà đơn là mình cố gắng chưa đủ nhé.

Liệu bạn đã bắt kịp xu thế công nghệ? – Áp lực đặc thù của ngành IT

Công nghệ có nghĩa quan trọng vì nó không thể tách rời khỏi công việc của ngành lập trình. Chính mối quan hệ chặt chẽ ấy đã vô tình tạo ra áp lực đặc thù của ngành IT

Bạn thử nghĩ xem liệu những giải pháp xưa cũ có còn ứng dụng được vào bộ máy vận hành hoạt động của các tổ chức vừa áp dụng các mô hình công nghệ hiện đại? Nhiều yếu tố trong ngành IT như các công cụ công nghệ, thuật ngữ ngôn ngữ lập trình, framework,.. dường như mọi thứ đều được thay đổi.

Chính áp lực đó đã tạo nên cho dân IT một nỗi lo lớn. Họ rất sợ kiến thức của mình bị lạc hậu và khó khăn trong vấn đề tìm kiếm việc làm do thị trường đầy cạnh tranh và rủi ro bị đào thải nếu không đáp ứng được cầu. Những developer lâu năm chắc chắn thấm thía những áp lực này rồi.

  6 giải pháp công nghệ hữu ích cho phòng nhân sự của bạn

ngành lập trình

Đúc kết từ kinh nghiệm thực tế, dưới đây là những cách mình dùng để tránh những áp lực này. 

  • Tập trung nắm vững những kiến thức căn bản trước vì nó là cơ sở giúp bạn dễ dàng hơn trong việc tiếp cận công nghệ
  • Trải nghiệm thực tế thông qua việc tham gia và thực hiện những dự án lớn nhỏ để áp dụng những kiến thức IT đã tích lũy
  • Đừng lo lắng quá nhiều về công nghệ. Hãy rèn luyện về tính tư duy độc lập và tư duy hệ thống để nắm bắt cơ chế đồng thời liên tục cập nhật những thông tin mới về ngành lập trình IT

Áp lực nảy sinh từ quá trình thực hiện công việc/dự án

Cuộc sống này không quá dễ dàng đối với chúng ta. Khi bạn có một người sếp hoàn hảo và những đồng nghiệp tuyệt vời thì bạn nghĩ chắc mình không cần phải lo nghĩ nhiều về những áp lực xoay các mối quan hệ. Tuy nhiên, đừng vội vui mừng vì vẫn còn tổn tại một loại áp lực mà dù bạn có muốn trốn tránh cũng không thể tránh được. Đó là áp lực nảy sinh từ quá trình thực hiện công việc hoặc dự án.

ngành lập trình

Nếu đối với dự án nhỏ, khối lượng công việc không quá nhiều nên bạn khá thảnh thơi. Tuy nhiên, với các dự án lớn đòi hỏi độ phức tạp cao, bạn sẽ khó thể chối từ lời mời “đồng hành” của người bạn mang tên áp lực. 

Dự án quá phức tạp, quá khó khăn khi code; team chịu trách nhiệm thực hiện dự án lại không đủ về nguồn lực và chuyên môn. Trong khi thời gian hoàn thành dự án quá gấp rút và vượt tầm kiểm soát khiến nhân lực phải thực hiện trong điều kiện chạy hết tố lực. Cảm giác khó chịu và tất nhiên việc phải OT (OverTime) “điên cuồng” là điều khó tránh khỏi.

Nếu cố gắng, bạn có thể thoát khỏi nó được không? Tất nhiên là được chứ, nhưng bạn phải buông bỏ suy nghĩ của việc trốn chạy, phải đối diện với áp lực vì đó là cách tốt nhất để “lật bài ngửa” giúp giảm thiểu những áp lực có thể diễn ra. Bạn có thể tham khảo một số cách thức làm bạn với những áp lực như sau:

  • Hãy thảo luận với các anh chị Leader hoặc quản lý dự án (Project Manager) xem có cách nào đàm phán với khách hàng (Clients) để kéo dài được deadline hay không?
  • Ngoài ra, việc chăm sóc sức khỏe là điều quan trọng để ứng phó với các áp lực. Ăn uống điều độ, ngủ không quá khuya, không cố gắng làm việc khi cơ thể có dấu hiệu mệt mỏi.

Lời kết

Áp lực trong ngành IT dễ hay khó vượt qua là do bản thân bạn quyết định vì đơn giản không riêng gì ngành lập trình mà rất nhiều ngành/lĩnh vực đều tồn tại những áp lực. Điều quan trọng là bạn có biết nhận ra được áp lực, đối mặt và tìm cách vượt qua nó. Mong rằng với bài viết vừa rồi, các bạn sẽ có những hình dung cụ thể về những áp lực diễn ra trong thực tế của những người làm về IT.

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

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

8 thủ thuật khi làm việc với Object sử dụng resting và spreading

8 thủ thuật khi làm việc với Object sử dụng resting và spreading
Bài viết được sự cho phép của tác giả Lưu Bình An
Những đoạn code bỏ túi hay xài nhất khi đụng tới object
  JavaScript đã tạo ra Object từ Function như thế nào?
  Object Relational Mapping

Merge object

part1 và part2 sẽ được merge vào user1

const part1 = { id: 100, name: 'An Luu' }
const part2 = { id: 100, password: 'Password!' }

const user1 = { ...part1, ...part2 }
//=> { id: 100, name: 'An Luu', password: 'Password!' }

Thêm property

Clone một object đồng thời thêm một số property mới vào object mới clone

const user = { id: 100, name: 'An Luu'}
const userWithPass = { ...user, password: 'Password!' }

user //=> { id: 100, name: 'An Luu' }
userWithPass //=> { id: 100, name: 'An Luu', password: 'Password!' }

Thêm property khi thỏa điều kiện

Trường hợp này hay dùng nhất là lúc chúng ta truyền lên API một object, nếu thõa điều kiện, sẽ thêm một số property vào trong object

const user = { id: 100, name: 'An Luu' }
const password = 'Password!'
const userWithPassword = {
  ...user,
  id: 100,
  ...(password && { password })
}

userWithPassword //=> { id: 100, name: 'An Luu', password: 'Password!' }

Xóa property khỏi object

// hàm này sẽ trả về object mới ko bao gồm password
const noPassword = ({ password, ...rest }) => rest

const user = {
  id: 100,
  name: 'An Luu',
  password: 'Password!'
}

noPassword(user) //=> { id: 100, name: 'An Luu' }

Xóa property với key chỉ định

const user1 = {
  id: 100,
  name: 'An Luu',
  password: 'Password!'
}

const removeProperty = prop => ({ [prop]: _, ...rest }) => rest
//                     ----       ------
//                          \   /
//                dynamic destructuring

const removePassword = removeProperty('password')
const removeId = removeProperty('id')

removePassword(user1) //=> { id: 100, name: 'An Luu' }
removeId(user1) //=> { name: 'An Luu', password: 'Password!' }

Sắp xếp property

Đôi khi chúng ta sẽ muốn thay đổi các property theo một thứ tự nào đó, nếu sắp xếp toàn bộ luôn thì chắc dùng Object.keys rồi thay xếp cái mảng key này lại.

Để di chuyển id lên đầu, trước hết gán giá trị undefined cho nó trước, sau đó, override lại giá trị này bằng cách resting

const user3 = {
  password: 'Password!',
  name: 'An Luu',
  id: 300
}

const organize = object => ({ id: undefined, ...object })
//                            -------------
//                          /
//  dời id lên đầu

organize(user3)
//=> { id: 300, password: 'Password!', name: 'An Luu' }

Còn di chuyển xuống dưới cùng

const user3 = {
  password: 'Password!',
  name: 'An Luu',
  id: 300
}

const organize = ({ password, ...object }) =>
  ({ ...object, password })
//              --------
//             /
// dời password xuống cuối

organize(user3)
//=> { name: 'An Luu', id: 300, password: 'Password!' }

Property mặc định

Ví dụ, user2 không có chứa quotes, hàm setDefaults đảm bảo tất cả object đều chứa property là quotes, nếu ko nó thêm vào []

const user2 = {
  id: 200,
  name: 'An Luu'
}

const user4 = {
  id: 400,
  name: 'You',
  quotes: ["I've got a good feeling about this..."]
}

const setDefaults = ({ quotes = [], ...object}) =>
  ({ ...object, quotes })

// hoặc nếu muốn dời thằng quotes lên đầu
// const setDefaults = ({ ...object}) => ({ quotes: [], ...object })

setDefaults(user2)
//=> { id: 200, name: 'An Luu', quotes: [] }

setDefaults(user4)
//=> {
//=>   id: 400,
//=>   name: 'You',
//=>   quotes: ["I've got a good feeling about this..."]
//=> }

Đổi tên property

Thí dụ bạn ko muốn trong object chứa property ID, nó phải viết thường id, đầu tiên chúng ta remove ID ra khỏi object, sau đó add lại bằng tên là id

const renamed = ({ ID, ...object }) => ({ id: ID, ...object })

const user = {
  ID: 500,
  name: "An Luu"
}

renamed(user) //=> { id: 500, name: 'An Luu' }

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

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

Xem thêm các vị trí tuyển dụng IT hấp dẫn tại TopDev

for vs forEach vs for/in vs for/of trong javascript

for-vs-foreach-vs-for-in-vs-for-of-trong-javascript
Bài viết được sự cho phép của tác giả Lưu Bình An
Trong javascript có rất nhiều cách để loop qua một array, chúng ta cùng bàn qua 4 cách chính hay sử dụng nhất
  • for (let i = 0; i < arr.length; ++i)
  • arr.forEach((v, i) => { /* ….. */})
  • for (let i in arr)
  • for (const v of arr)

2 phương thức là for và for/in cho phép chúng ta truy cập đến giá trị index trong array, ko phải giá trị của element trong array

const arr = ['a', 'b', 'c'];
// sau đó chúng ta dùng truy cập element bằng giá trị index
for (let i = 0; i < arr.length; ++i) {
  console.log(arr[i]);
}

for (let i in arr) {
  console.log(arr[i]);
}

Trong khi đó hai phương thức for/of và forEach sẽ truy xuất đến phần tử trong element, cũng có thể truy xuất vào index, nếu thích.

arr.forEach((v, i) => console.log(v));
for (const v of arr) {
  console.log(v);
}

Có thể bạn chưa biết, array trong javascript cũng là một dạng đặc biệt của object, chúng ta có thể gán một property cho nó

const arr = ['a', 'b', 'c'];
console.log(typeof arr); // 'object'

arr.test = 'bad';
console.log(arr.test); // bad

arr[1] === arr['1']; // true,

Nếu loop qua bằng 4 phương thức trên, chỉ duy nhất thằng for/in sẽ chạy qua

const arr = ['a', 'b', 'c'];
arr.test = 'bad';

// "a, b, c, bad"
for (let i in arr) {
  console.log(arr[i]);
}

Đó là lý do tại sao chúng ta ko nên dùng for/in để loop qua array

Đối với một element trống như thế này

const arr = ['a',,'b']
console.log(arr.length); // 3

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

Không chỉ vậy thôi đâu, nếu loop qua mảng ['a',,'b'] nó cũng sẽ khác với ['a', undefined, 'c']. 2 thằngfor/infor/eachsẽ bỏ qua phần tử trống như vậy, nhưngforfor/of` vẫn tính

const arr = ['a',, 'c']
// Prints "a, undefined, c"
for (let i = 0; i < arr.length; ++i) {
  console.log(arr[i]);
}

// Prints "a, c"
arr.forEach(v => console.log(v));

// Prints "a, c"
for (let i in arr) {
  console.log(arr[i]);
}

// Prints "a, undefined, c"
for (const v of arr) {
  console.log(v);
}

Tuy nhiên, nếu là ['a', undefined, 'c'], cả 4 phương thức trên đề print hết giá trị trong array.

  10 câu hỏi JavaScript để tăng cường kỹ năng của bạn
  Giới thiệu về Reactive Programing trong javascript

Một cách để chèn phần tử trống vào array

const arr = ['a', 'b', 'c'];
arr[5] = 'e';

Tuy nhiên là trường hợp [a, , c] này sẽ rất rất ít khi xảy ra, vì căn bản là file JSON như thế là không hợp lệ. Chúng ta cũng không cần lo lắng lắm

> JSON.parse('{"arr":["a","b","c"]}')
{ arr: [ 'a', 'b', 'c' ] }
> JSON.parse('{"arr":["a",null,"c"]}')
{ arr: [ 'a', null, 'c' ] }
> JSON.parse('{"arr":["a",,"c"]}')
SyntaxError: Unexpected token , in JSON at position 12

Với từ khóa thisforfor/infor/of sẽ dùng chung scope với thằng cha, trong khi forEach thì nó là scope của nó.

forEach cũng xảy ra nhiều tình huống ko đúng khi dùng với async/await hoặc generator. Code bên dưới là không chạy, không dùng await cho callback của forEach cũng như yield

async function run() {
  const arr = ['a', 'b', 'c'];
  arr.forEach(el => {
    // SyntaxError
    await new Promise(resolve => setTimeout(resolve, 1000));
    console.log(el);
  });
}

function* run() {
  const arr = ['a', 'b', 'c'];
  arr.forEach(el => {
    // SyntaxError
    yield new Promise(resolve => setTimeout(resolve, 1000));
    console.log(el);
  });
}

Dùng với for/of thì ok

async function asyncFn() {
  const arr = ['a', 'b', 'c'];
  for (const el of arr) {
    await new Promise(resolve => setTimeout(resolve, 1000));
    console.log(el);
  }
}

function* generatorFn() {
  const arr = ['a', 'b', 'c'];
  for (const el of arr) {
    yield new Promise(resolve => setTimeout(resolve, 1000));
    console.log(el);
  }
}

Túm lại, for/of có thể dùng gần như mọi lúc. Mặc dù performance ko bằng for, nhưng dễ xài hơn, cũng ko dính nhiều trường hợp đặc biệt như for/in và forEach. Nếu ko cần dùng đến giá trị index, thì for/of sẽ được dùng. Còn nếu muốn truy xuất tới giá trị index với for/of

for (const [i, v] of arr.entries()) {
  console.log(i, v); // Prints "0 a", "1 b", "2 c"
}

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

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

Xem thêm các việc làm IT tại Hồ Chí Minh, Hà Nội hấp dẫn tại TopDev

Khi nào thì sử dụng Generics trong TypeScript

Khi nào thì sử dụng Generics trong TypeScript

Bài viết được sự cho phép của tác giả Vũ Công Tấn Tài

Trong TypeScript, có một kiểu dữ liệu khá đặc biệt, đó là kiểu generics. Với generic, chúng ta có thể viết ra các hàm / components / modules mà không nhất thiết phải chỉ định rõ kiểu dữ liệu lúc định nghĩa. Khai báo kiểu dữ liệu sẽ được đẩy về lúc sử dụng components đó. Như vậy, lúc sử dụng, nếu chúng ta chỉ định kiểu dữ liệu là number thì component sẽ chỉ chấp nhận dữ liệu kiểu number, tương tự như vậy, chúng ta có thể chỉ định kiểu dữ liệu cụ thể bất kì lúc sử dụng.

  Học kiến thức căn bản TypeScript chỉ trong 30 phút
  Frontend là gì? Làm thế nào để trở thành một Frontend developer

Với sự tiện dụng đó, bạn có thể thắc mắc, tại sao chúng ta không luôn sử dụng kiểu generics? Khi nào chúng ta nên dùng generics, khi nào nên chỉ định rõ kiểu dữ liệu lúc định nghĩa components? …

Giả định một tình huống cụ thể

Chương trình của chúng ta có 1 hàm trả về đối tượng “già nhất” trong 1 tập dữ liệu:

1
2
3
function getOldest(items: Array<{ age: number }>) {
    return items.sort((a, b) => b.age - a.age)[0];
}

Có thể thấy, hàm này chấp nhận kiểu dữ liệu đầu vào là 1 object bất kì, với điều kiện là nó phải có thuộc tính age. Để rõ ràng hơn, ta sẽ định nghĩa kiểu dữ liệu cho ràng buộc này như sau:

1
type HasAge = { age: number };

Như vậy, hàm của chúng ta sẽ được viết lại rõ ràng hơn như sau:

1
2
3
function getOldest(items: HasAge[]): HasAge {
    return items.sort((a, b) => b.age - a.age)[0];
}

Với ngữ cảnh này, chúng ta chạy một đoạn mã kiểm tra có sử dụng hàm trên như sau:

1
2
3
4
const things = [{ age: 10 }, { age: 20 }, { age: 15 }];
const oldestThing = getOldest(things);
console.log(oldestThing.age); // 20

Có thể thấy, vì dữ liệu trả về từ hàm getOldest() là một đối tượng có “hình dạng” tuân theo kiểu HasAge, do đó nó sẽ có thuộc tính age, vì thế ta có thể in ra độ tuổi của nó bằng cách gọi oldestThing.age. Cho tới lúc này đoạn mã của chúng ta viết vẫn đáp ứng tốt yêu cầu.

Vấn đề xảy ra khi chúng ta sử dụng kiểu dữ liệu phức tạp hơn

Giả sử, chúng ta có kiểu dữ liệu là Person, và tất nhiên, người thì có thuộc tính age, vì dữ liệu kiểu Person bao hàm luôn kiểu dữ liệu HasAge, nên ta có thể sử dụng được hàm getOldest() đối với dữ liệu kiểu Person.

1
2
3
4
5
6
7
8
9
type Person = { name: string, age: number};
const people: Person[] = [
    { name: 'Amir', age: 10 },
    { name: 'Betty', age: 20 },
    { name: 'Cecile', age: 15 }
];
const oldestPerson = getOldest(people); // This is OK

Vậy vấn đề ở đâu? Vấn đề là: kể cả khi ta sử dụng hàm getOldest với một kiểu dữ liệu khác (lớn hơn), dữ liệu trả về chỉ có kiểu dữ liệu là HasAge.

Chính vì kiểu dữ liệu trả về có kiểu là HasAge (chứ không phải kiểu Person), nên đoạn code sau sẽ báo lỗi khi ta truy cập vào thuộc tính name:

1
console.log(oldestPerson.name); // ❌ type error: Property 'name' does not exist on type 'HasAge'.

Rõ ràng, khi ta truyền vào mảng people có kiểu dữ liệu là Person, đối tượng trả về sẽ có thuộc tính name. Tuy nhiên, vì ta đã “hard-code” kiểu dữ liệu trả về của ta là HasAge, vậy nên trình thông dịch của TypeScript sẽ không chấp nhận cho ta truy cập bất kì thuộc tính nào khác ngoài ageChương trình của ta đã mất đi tính linh động.

Kể cả khi ta cố tình ép kiểu, TypeScript vẫn sẽ báo lỗi:

1
2
const oldestPerson: Person = getOldest(people); // ❌ type error
// Property 'name' is missing in type 'HasAge' but required in type 'Person'.

Kể cả khi ta có thể “lách luật” trình biên dịch với type assertions, thì đó cũng không phải là 1 cách làm tốt.

1
2
const oldestPerson = getOldest(people) as Person; // Lách luật
console.log(oldestPerson.name); // no type error

(Thử đoạn mã trên với TypeScript Playground)

Khi Generics phát huy tác dụng

Vì chương trình của ta đã bị mất đi tính linh động, ta có thể dùng generics để cải tiến như sau:

1
2
3
4
5
function getOldest<T extends HasAge>(items: T[]): T {
    return items.sort((a, b) => b.age - a.age)[0];
}
const oldestPerson = getOldest(people); // ✅ type Person

Done! Với việc sử dụng kiểu dữ liệu linh động, giờ ta biến oldestPerson của chúng ta đã kiểu dữ liệu là Person, và kiểu dữ liệu này linh động phù hợp đúng theo kiểu dữ liệu đã truyền vào.

Như vậy, ta đã có thể truy cập được thuộc tính name của dữ liệu trả về mà không bị TypeScript báo lỗi nữa:

1
2
const oldestPerson = getOldest(people); // ✅ type Person
console.log(oldestPerson.name);  // OK

Ta có thể kiểm tra với nhiều kiểu dữ liệu khác ở đây:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
type Person = {name: string, age: number};
const people: Person[] = [
    { name: 'Amir', age: 10 },
    { name: 'Betty', age: 20 },
    { name: 'Cecile', age: 15 }
 ];
type Bridge = {name: string, length: number, age: number};
const bridges = [
    { name: 'London Bridge', length: 269, age: 48 },
    { name: 'Tower Bridge', length: 244, age: 125 },
    { name: 'Westminster Bridge', length: 250, age: 269 }
]
const oldestPerson = getOldest(people); // type Person
const oldestBridge = getOldest(bridges); // type Bridge
console.log(oldestPerson.name); // 'Betty' ✅
console.log(oldestBridge.length); // '250' ✅

(Thử đoạn mã trên với TypeScript Playground ở đây)

Khi nào không nên dùng Generics?

Kể cả khi bạn sử dụng dữ liệu đầu vào có kiểu là HasAge hay là một dữ liệu phủ lớn hơn của nó, nếu dữ liệu trả về của bạn không cần linh hoạt, hoặc không liên quan gì tới kiểu dữ liệu truyền vào, lúc đó bạn không cần sử dụng Generics làm gì cả. Ví dụ: trường hợp này sử dụng generics là không cần thiết.

1
2
3
function isFirstOlder<T extends HasAge>(a: T, b: T) {
    return a.age > b.age;
}

Có thể thấy, generics không phát huy được ưu điểm của nó trong tình huống này. Với xử lí ở trên, đơn giản ta chỉ cần làm như sau:

1
2
3
function isFirstOlder(a: HasAge, b: HasAge) {
return a.age > b.age;
}

 

Bài viết gốc được đăng tải tại Những dòng code vui

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

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

Khó khăn của một CTO – Chief Technology Officer

cto

Để có thể hiểu rõ những khó khăn của CTO hay gặp phải thì việc đầu tiên chúng ta cần định hình được định nghĩa CTO và vai trò của CTO trong công ty, sự khác biệt của CTO và CIO là gì? Từ đó đúc kết được những khó khăn mà CTO sẽ gặp phải.

Nếu sau khi đọc xong bài tổng hợp này từ TopDev mà bạn vẫn cảm thấy hứng thú với vai trò CTO và cảm thấy đây mà một thách thức đáng để trải nghiệm thì chúc mừng bạn, cơ hội trải nghiệm vị trí CTO tại TopDev chào mừng bạn! 

CTO là gì?

Theo nghĩa tiếng anh CTO – Chief Technology Officer, được hiểu là Giám đốc Công nghệ. Tuy nhiên khái niệm này khá rộng và mơ hồ, vậy công việc thực sự của CTO là gì?

Có thể hiểu nôm na CTO là người đưa ra những quyết định mang tính mấu chốt liên quan đến những vấn đề về công nghệ trong công ty. Họ sẽ là người nhìn thấu và có thể đo lường mức độ thành công của bất cứ dự án nào liên quan đến công nghệ. Thật ra thì, không có một từ ngữ hay một định nghĩa cụ thể nào để diễn đạt được vai trò của CTO. Một CTO ở công ty lớn sẽ có công việc và trách nhiệm khác với một CTO ở một Startup, ví dụ, ngoài việc phải xử lý những vấn đề liên quan đến kỹ thuật thì CTO của công ty Startup thường phải đảm nhận thêm những vấn đề liên quan đến cả sản phẩm (nếu công ty đó là công ty công nghệ), marketing, kinh doanh….

Nói chung, CTO là vị trí của một giám đốc đa năng, họ không cần phải là một người cực kì giỏi hay có chuyên môn quá sâu nhưng nhất thiết phải có những kiến thức nền tảng cũng như kỹ năng giải quyết vấn đề trong nhiều lĩnh vực, tầm nhìn xa, khả năng thấu hiểu và dẫn dắt nhân viên thay vì chỉ tập trung phát triển bản thân để có thể đảm bảo mọi thứ trong công ty đều vận hành trơn tru. Đặc biệt, trong một công ty công nghệ, vai trò của CTO là cực kì to lớn, hầu như những vấn đề nào xảy ra đều có mặt của CTO đứng ra giải quyết.

  CTO là gì - Những sự thật cần biết về Chief Technology Officer 

Thông thường các Giám đốc Công nghệ có 2 chức năng chính, đó là quan sát và chăm lo cho quy trình hoạt động kinh doanh nội bộ như phát triển tính năng sản phẩm. Chức năng thứ hai của CTO là họ sẽ là gương mặt đại diện cho công ty của họ để đi tham gia các sự kiện, hội nghị thương mại nhằm củng cố và nâng cao vị thế của doanh nghiệp trong giới.

Những năm trở lại đây, công nghệ ngày càng được ứng dụng nhiều hơn, từ những việc đơn giản nhất như thanh toán, đọc báo… cũng đều được công nghệ hóa tối đa. Công nghệ được nâng cấp và sử dụng để giảm các chi phí không cần thiết khi vận hành công ty, bên cạnh đó, công nghệ cũng được áp dụng để phân tích xu hướng thị trường và hoạch định được lợi nhuận trong hầu hết các ngành nghề hiện nay.

CTO chịu trách nhiệm cho tất cả các khía cạnh liên quan đến công nghệ trong 1 tổ chức, mỗi khi nền công nghệ có một bước tiến mới thì CTO sẽ là người chịu trách nhiệm cho việc cập nhật xu hướng mới đó. Họ cần phải có khả năng cân bằng giữa chiến lược kinh doanh và chiến lược công nghệ thay vì chỉ mãi tập trung nâng cao lợi nhuận giống như vị trí CEO trong công ty.

Sự nhầm lẫn giữa CTO và CIO – Chief Information Officer

Khái niệm giữa CTO và CIO rất dễ bị mọi người hiểu lầm chung là 1 hoặc hiểu sai vai trò của nhau. Thật ra, Giám đốc Thông tin (CIO) có nhiệm vụ chịu trách nhiệm và mảng công nghệ thông tin, ở một vài công ty nhỏ, vai trò của 2 vị trí này thường được gộp lại làm 1 vì sự tương đồng là ‘Công nghệ’. Có thể hiểu, CIO là người chịu trách nhiệm về việc phát triển kỹ thuật công nghệ cho công ty, duy trì và đảm bảo cơ sở hạ tầng Công nghệ Thông tin cho công ty.

Tuy nhiên, vì sự phát triển ‘khủng bố’ của nền công nghệ hiện nay, đồng nghĩa với việc khối lượng công việc của một CIO cũng ngày càng tăng, chính vì thế từ đó mới có sự xuất hiện của CTO nhằm chia sẻ bớt phần nào gánh nặng công việc của CIO và vai trò CTO cũng đã phát triển thêm nhiều chức năng quản lý khác để vận hành doanh nghiệp tốt hơn.

Tùy vào quy mô, phạm vi ngành nghề hoạt động của công ty mà trách nhiệm của CTO sẽ thay đổi theo sao cho phù hợp với công ty đó. Ví dụ, tại một Startup nhỏ, chưa có khả năng để tự thành lập team kỹ thuật riêng của công thì Giám đốc Công nghệ sẽ là người chịu trách nhiệm quản lý và làm việc với nguồn outsource ở bên ngoài sao cho có thể hoàn thành tốt việc vận hành phát triển cũng như giúp công ty đạt được các mục tiêu tài chính và tiếp thị bằng công nghệ tiên tiến.

Thông thường, CTO không có mức lương quy chuẩn nào cả vì như ở trên, CTO thường không có trách nhiệm nhất định, nên mức lương cũng sẽ lên xuống theo đó. Theo số liệu mới nhất vào năm 2020 thì mức lương trung bình cho vị trí CTO giao động trong khoản 159,920$/năm, trong trường hợp đối với các công ty công nghệ thì mức lương trung bình mỗi năm của CTO công ty công nghệ là vào khoảng 200,000$/năm.

cto

Khó khăn của một CTO

Phải đưa ra quyết định có tầm nhìn về nền tảng, thiết kế kỹ thuật

Vị trí CTO sẽ là người lao đầu vào tất tần tật những kế hoạch, dự án có liên quan đến công nghệ, kỹ thuật của công ty. Bên cạnh đó họ còn phải duy trì cân bằng cho các chiến lược phát triển của một dự án, đồng thời phải triển khai ý tưởng để thực hiện dự án đó thành công. Ở một vài công ty Startup nhỏ trẻ, một trong những thành viên sáng lập thường là người chịu trách nhiệm cho vị trí CTO, còn nếu ở một công ty lớn thì CTO sẽ là người phân phối công việc, vận hành team kỹ thuật, lập trình viên hoặc những bộ phận có trách nhiệm về mảng công nghệ của công ty.

Trong một số trường hợp đặc biệt, thường là ở các công ty công nghệ thì Giám đốc Công nghệ có thể vừa là người chịu trách nhiệm về công nghệ vừa là người kiêm luôn trách nhiệm đưa ra quyết định cho các kế hoạch phát triển, kinh doanh, thiết kế, sản phẩm có liên quan đến công nghệ.

Không những thế, nếu nguồn nhân lực về công nghệ trong một công ty không đủ kiến thức cũng như kinh nghiệm, tài nguyên để đáp ứng nhu cầu công việc thì chắc chắn rằng CTO sẽ là người có trách nhiệm tìm ra giải pháp hợp lý để giải quyết vấn đề này. Chính vì thế, nói CTO là một giám đốc đa năng cũng không ngoa vì để đảm nhiệm vị trí này ngoài có sự hiểu biết về lĩnh vực công nghệ thì họ cũng cần phải nắm được các kỹ năng đa dạng khác để có thể hoàn thành công việc.

  Lời khuyên từ Việt Trần - CTO DOF Hunt “Cách quản trị tốt nhất chính là không quản trị”
  Gặp gỡ Nguyễn Sơn Tùng CTO Viec.co - Quán quân StartupViet 2019

Đảm bảo chất lượng nhân sự team công nghệ

Ngoài những trách nhiệm công việc đã nêu trên, Giám đốc Công nghệ có thể còn kiêm luôn cả vị trí HR, chịu trách nhiệm phỏng vấn và tuyển dụng các chuyên viên kỹ thuật, chuyên viên khoa học dữ liệu và kỹ sư công nghệ. Trong những năm gần đây, việc tuyển dụng ngày càng trở nên khó khăn cho các Startup, thị trường càng ngày càng đa dạng, ứng viên ngày càng có nhiều sự lựa chọn hơn. Nguồn cầu lớn hơn nguồn cung nên các ứng viên sáng giá cho vị trí công nghệ có xu hướng lựa chọn cho bản thân một môi trường hoàn hảo nhất có thể, nhưng hầu hết những startup trẻ lại chưa đủ lực để đáp ứng được nhu cầu đó. Chính vì thế, để đảm bảo chất lượng nhân sự team công nghệ chưa bao giờ là một nhiệm vụ dễ dàng cả.

cto

Dù thích hay không, dù HR có hỗ trợ hay không thì Giám đốc Công nghệ vẫn luôn là người chịu trách nhiệm tuyển dụng, phỏng vấn, giám sát và đào tạo một đội ngũ hoàn hảo có thể hỗ trợ vận hành kỹ thuật công nghệ của công ty một cách trơn tru. Thậm chí các CTO ngày nay còn rất quan tâm đến các kỹ năng tuyển dụng.

Đảm bảo hệ thống an toàn

Bên cạnh việc quản lý bộ phận kỹ thuật của công ty thì việc đảm bảo tính an toàn của hệ thống cũng là công việc trong list trách nhiệm của một CTO. Cơ sở dữ liệu của công ty là một nơi cần được bảo mật tuyệt đối, nhiệm vụ của CTO là điều động team kỹ thuật lắp kín các lỗ hổng bảo mật và phát triển, xây dựng lớp tường thành bảo vệ nó. CTO phải đảm bảo các thông tin của công ty cũng như khách hàng của công ty được thuật toán bảo mật tuyệt đối, giữ được sự riêng tư. Đồng thời các kỹ sư kỹ thuật cũng phải làm việc theo quy tắc bảo mật do CTO đặt ra.

Đảm bảo chất lượng các sản phẩm công nghệ

Vai trò này được thể hiện mạnh mẽ khi Giám đốc Công nghệ làm trong các công ty phát triển sản phẩm công nghệ. Các bộ phận đảm bảo chất lượng của các công ty Startup công nghệ trẻ thường rất non nớt và yếu. Nhiệm vụ của các CTO ở đây là kiểm tra sản phẩm và đưa ra những thay đổi giúp cải thiện các chức năng sản phẩm, ngoài ra Giám đốc Công nghệ cũng sẽ chỉ định bộ phận nào hoặc ai là người chịu trách nhiệm chính trong quá trình debug.

Đóng góp ý kiến phát triển sản phẩm

Bên cạnh những nghĩa vụ trên CTO còn chịu trách nhiệm về việc phát triển sản phẩm mới và áp dụng công nghệ mới lên sản phẩm tiếp theo. Từ việc nghiên cứu, phân tích phản hồi từ khách hàng và hợp tác với các phòng ban khác, chắc chắn vai trò đóng góp để phát triển sản phẩm mới của CTO là không thể thiếu trong công ty công nghệ.

Học hỏi các kỹ năng mềm

Ngoài sự nổi trội trong lĩnh vực chính của mình thì điểm mạnh của CTO còn được thể hiện qua kinh nghiệm vận hành, quản lý và phát triển công ty thông qua các kỹ năng mềm. Quy mô công ty càng lớn thì càng có những yêu cầu kỹ năng cao hơn để thích ứng được với nhu cầu phát triển của công ty.

cto

  • Kỹ năng đàm phán là một trong những kỹ năng được các Giám đốc Công nghệ chú trọng hàng đầu, vì vai trò của CTO là quản lý đội ngũ kỹ thuật, tuyển dụng các ứng viên tiềm năng, làm việc với đối tác dự án kỹ thuật, thảo luận với giám đốc cấp cao và thậm chí là gặp khách hàng lớn.
  • Kỹ năng giải quyết vấn đề cũng được Giám đốc Công nghệ chú trọng vì khi có vấn đề kỹ thuật xảy ra thì CTO sẽ là người đầu tiên đưa ra kế hoạch giải pháp để khắc phục được điều đó.
  • Kỹ năng lãnh đạo, đây là một kỹ năng cần phải có ở dù ở bất cứ vị trí quản lý nào. Một CTO giỏi sẽ có thể lãnh đạo được team kỹ thuật của mình đạt được những thành tựu nhất định trong ngành.
  • Kỹ năng truyền cảm hứng cũng là một kỹ năng mà CTO cần bồi dưỡng để có thể nạp lại tinh thần cho nhân viên của mình nâng cao hiệu quả công việc. 
  • Kỹ năng tech tốt để hỗ trợ xây dựng kiến trúc sản phẩm kỹ thuật số, MVP và lập trình API và test, quản trị hệ thống công nghệ cao của công ty, các kỹ năng DevOps – tất cả kỹ năng này bạn có thể tìm thấy khi đọc bảng mô tả công việc CTO trong nhiều công ty khác nhau. Bộ kỹ năng này sẽ được yêu cầu tùy vào quy mô và đặc thù công nghệ của mỗi công ty.
  • Kỹ năng hoạch định chiến lược, CTO là người lên kế hoạch cho dự án kỹ thuật, họ cũng là người đưa ra quyết định cách tiếp cận phát triển quy trình làm việc, lập kế hoạch và kiểm tra ngân sách cùng với những bộ phận khác. Chính vì vậy CTO là người cần phải có kỹ năng lên kế hoạch chiến lược. Có thể nói CTO là người có cái nhìn tổng quan về toàn bộ công ty từ dự án đến các bộ phận khác nhau trong công ty miễn là liên quan đến công nghệ.
  Top 5 kỹ năng mềm mà các kỹ sư phần mềm cần phải biết
  Bài học về kỹ năng giải quyết vấn đề - Hãy tư duy như một Lập trình viên!
  Muốn vượt trội hơn người khác, không thể bỏ qua những kỹ năng cần thiết sau

Đút kết từ những thông tin trên mạng thì thật khó để có thể phân biệt được vị trí và vai trò chính xác của CTO và CIO cũng như những khó khăn khi làm Giám đốc Công nghệ. Nhưng bạn có thể hiểu nôm na là CTO là người sẽ sở hữu nhiều kỹ năng mềm và kỹ năng cứng nổi bật. Họ đóng vai trò quan trọng trong khía cạnh kỹ thuật của một doanh nghiệp, thấu hiểu và cân bằng nhu cầu của nhân viên, khách hàng. Tùy vào từng công ty, vai trò của CTO sẽ có những thay đổi nhất định để phù hợp với quy mô cũng như lĩnh vực của công ty đó.

Vai trò Giám đốc Công nghệ “khó chơi” ở chỗ họ phải thật sự thấu hiểu nhiều khía cạnh khác nhau của công việc. Ngoài ra họ còn đảm nhiệm rất nhiều nhiệm vụ công việc khác nhau, vị trí này khó có thể định nghĩa được là cần phải làm những gì. Có thể ở công ty A, bạn đảm nhiệm vị trí CTO rất tốt nhưng nó không đồng nghĩa với việc bạn cũng sẽ làm tốt vị trí CTO ở một công ty B. 

Quả là một công việc phức tạp nhỉ? Nhìn chung nếu bạn có kỹ năng hoạch định chiến lược, đảm bảo được vấn đề an ninh, chất lượng công nghệ cho công ty, xây dựng thành công team kỹ thuật giỏi, cập nhật xu hướng công nghệ mới và có thể vận hành tốt công nghệ mới, tìm ra tìm ra các giải pháp hiệu quả cho các khó khăn về phần kỹ thuật thì có thể bạn khá là phù hợp với vai trò của một Giám đốc Công nghệ. Năm 2020 là một năm được các chuyên gia dự đoán sẽ là một năm công nghệ bùng nổ, chính vì thế nhu cầu săn lùng CTO và tuyển dụng các vị trí kỹ sư kỹ thuật tại các công ty là cực kỳ cao. Ghé thăm trang tuyển dụng của TopDev ngay để tìm thêm những vị trí phù hợp với năng lực của mình nhé!

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

Việt Nguyễn – Từ cơ duyên đồng hành cùng Tiki đến vị trí CTO tại Ticketbox

CTO là gì – Những sự thật cần biết về Chief Technology Officer

Lời khuyên từ Việt Trần – CTO DOF Hunt “Cách quản trị tốt nhất chính là không quản trị”

TopDev tổng hợp.

Xem thêm việc làm CTO trên TopDev

Lập trình viên đánh đổi gì khi theo ngành lập trình

lập trình viên

Bài viết này sẽ liệt kê ra những khó khăn mà một lập trình viên sẽ gặp phải, giúp bạn đọc sẽ có một cái nhìn thực tế hơn về ngành từ đó có thể đưa ra quyết định sáng suốt là có nên đánh đổi để theo nghề lập trình viên này hay không nha!

Ngành công nghệ ngày càng phát triển, đồng thời cũng kéo theo nhu cầu tuyển dụng lập trình viên ở các công ty lớn nhỏ. Chính vì thế, ngành lập trình hiện nay được xem là một ngành hot với mức thu nhập trung bình khá cao.

Nghề lập trình viên ở thời điểm hiện tại cũng là ngành xã hội đang cần và được nhiều bạn trẻ hứng thú và muốn tìm hiểu thêm về nó. Tuy nhiên, ngành nào cũng vậy, cũng sẽ có những mặt tối, những khó khăn riêng mà chỉ người trong ngành mới biết. Đằng sau những ánh hào nhoáng là những đánh đổi, trả giá mà ai trong ngành cũng biết điều ấy cả.

Những khó khăn có thể sẽ làm giảm hứng thú của bạn với nghề, nhưng nếu bạn chấp nhận những trả giá và đánh đổi nó để theo nghề lập trình viên thì TopDev tin chắc rằng bạn sẽ trở thành một lập trình viên giỏi trong tương lai không xa!

Khó khăn I: Cần phải học nhiều, dễ bị đào thải, tuổi nghề thấp

Lập trình viên là nghề ăn, ngủ và làm việc với công nghệ mà công nghệ thì thường xuyên thay đổi và cập nhật những thứ mới mẻ hơn. Chính vì thế, người làm thiên về công nghệ phải luôn học hỏi liên tục những cái mới nếu không sẽ rất dễ bị tuột lại phía sau và bị đào thải.

Như các bạn cũng biết, cách đây chưa đến 10 năm, khi nền công nghệ di động còn chưa phát triển mạnh mẽ như hiện tại, đồng thời cũng chưa có sự xuất hiện của iOS, Android… thì nghề lập trình app tại thời điểm đó khá mờ nhạt, và chỉ có những app nhỏ, không có nhiều tính năng trên điện thoại. Bởi thế, nếu các bạn không học hỏi và cập nhật những kiến thức công nghệ mới thì chắc hẳn sau từ 3-4 năm các bạn sẽ bị ‘outgame’.

lập trình viên

Biết đâu 5-10 năm nữa sẽ có thêm những ngành nghề mới hoặc những ngành nào sẽ bị loại bỏ và biến mất. Mấy năm trước, Flash được xem là một trong những nền tảng nổi tiếng, nhưng hiện tại nó hầu như đã biến mất trên thị trường và không còn ai sử dụng Flash nữa, dĩ nhiên những người làm ngành đấy thì không tìm được việc nữa. Nên là làm ngành này, các bạn không thể giữ cái tư tưởng học bao nhiêu đó kiến thức trong trường là đủ rồi. Ra đi làm, làm đúng đủ kiến thức đó tới lúc về già luôn là không được. Với đống kiến thức hiện tại của bạn bây giờ các bạn đủ để xài được 3-4 năm, nhưng sau đó những kiến thức đó có thể đã mai một và các đã tới lúc bạn phải học thêm kiến thức mới rồi.

Những người đã từng học Angular hiện tại đã chuyển qua dùng Angular 2 trở lên. Chưa kể ngôn ngữ lập trình các bạn dùng cũng sẽ đổi mới trong tương lai, chắc chắn ngôn ngữ Framework mà bạn hiện tại bạn đang dùng sau vài năm nó cũng biến đổi, nâng cấp hơn. React thì cập nhật lên thành React Hooks, nó là 1 cách viết khá là mới mà cách bạn phải học lại từ đầu. Do vậy sự học là bất tận, khi đã theo ngành lập trình viên là phải luôn học, không học là sẽ bị đào thải.

Bên cạnh việc lo sợ việc bị đào thải thì tuổi nghề của ngành cũng là một vấn đề nhiều bạn quan tâm. Bất cứ ngành nghề nào cũng vậy cả, chỉ khi bạn có đam mê thì bạn sẽ không bị đào thải. Có nhiều lập trình viên 3-40 tuổi thậm chí lên đến 50 là bình thường, tuổi nghề như thế nào không quan trọng bằng con người của bạn. Tuổi nghề của bạn sẽ ngắn nếu bạn là một người an phận và luôn thấy ‘như vậy là đủ rồi’, bạn không chịu cập nhật công nghệ liên tục, bạn dựa vào kinh nghiệm làm việc 5 năm, 10 năm của bạn để offer mức lương cao đủ để chăm lo cho gia đình, bạn vì bận chuyện gia đình, con cái nên không thể OT (làm ngoài giờ), không còn nhanh nhẹn để nắm bắt xu thế công nghệ mới như giới trẻ hiện nay thì bạn sẽ có tuổi nghề ngắn.

Ngược lại, có những lập trình viên theo nghề vì đam mê, luôn học hỏi cập nhật những thứ mới trong ngành thì sẽ trở thành ‘gừng càng già càng cay’. Thậm chí có những lập trình làm lâu có kinh nghiệm nhiều và đa dạng, họ có thể kiêm vị trí của 1 lập trình viên đa năng từ Systems Admin cho tới OS, Network database… những người như vậy thường có mức lương rất cao và không có chuyện họ bị đào thải.

Khó khăn II: Công việc áp lực và thường xuyên phải làm ngoài giờ

Công việc áp lực

Nghề lập trình viên này đa phần làm theo dự án là chính, khi đang trong dự án nào đó cần sản phẩm gấp chắc chắn 100% các bạn phải làm ngoài giờ. Ở các công ty Startup, khi phải ra mắt sản phẩm thì thường các lập trình viên sẽ phải tăng ca kể cả thứ 7, Chủ nhật hay lễ. Nhiều công ty sẽ chấp nhận trả lương khi bạn làm ngoài giờ, một số thì không và xem đó là 1 phần trong công việc.

Vì phải tăng ca như thế này đôi khi lập trình viên sẽ phải gặp vấn đề về các mối quan hệ vì không có thời gian dành cho gia đình, bạn bè, tình cảm… Lập trình viên không phải là một ngành nhàn hạ, thoải mái, ngành này áp lực nhiều hơn các bạn nghĩ rất nhiều đấy!

Khó khăn III: Gặp rào cản và bị ‘ngáo’ trong các mối quan hệ

Đa phần dân lập trình là những người có lối suy nghĩ logic, lập trình càng giỏi thì lại càng cần sự logic. Trong thế giới lập trình 1 là 1, 2 là 2 và đặc biệt lập trình viên đa số chỉ làm việc với máy tính và hệ thống, trong thế giới đó chỉ có đúng, sai. Tuy nhiên, quan hệ giữa con người với con người thì lại không như vậy, trong thế giới con người có tồn tại thứ gọi là tình cảm nên không thể phân biệt rạch ròi cái gì đúng hay sai.

Giữa dân lập trình với nhau, nếu các bạn nói chuyện liên quan đến kỹ thuật thì khi bạn đúng, team sẽ làm theo nhưng khi các bạn làm việc với team khác ngoài team lập trình thì nên cẩn thận nhé vì không phải cứ đúng logic và có thể giải quyết vấn đề là họ sẽ làm theo đâu mà bạn còn phải có kỹ năng nói chuyện khéo léo nữa kìa. Bởi vì môi trường làm việc xung quanh bạn chỉ toàn là dân lập trình nên đôi khi bạn sẽ bị ảnh hưởng cộng đồng, vừa khó để học hỏi được kỹ năng quan sát sắc mặt người khác, kỹ năng giao tiếp mà còn có thể trở nên ‘cục súc’ giống nhau.

Thực tế, công việc của các lập trình viên không cần phải có kỹ năng giao tiếp cao siêu gì cả nhưng kỹ năng giao tiếp là một kỹ năng rất quan trọng trong xã hội và trong các mối quan hệ con người với nhau. Cách để có thể nâng cao khả năng giao tiếp, tránh tình trạng trở nên ‘cục súc’ khi làm lập trình là các bạn đừng nên chỉ sinh hoạt chung với mỗi phòng ban của mình mà hãy giao lưu với những team khác nữa ví dụ như team marketing, design, sale…để học hỏi thêm.

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

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

Khó khăn IV: Lập trình viên lương cao nhưng khó để làm giàu

Lập trình viên lương cao

Bạn đừng quá hy vọng nghề lập trình sẽ giúp bạn trở nên giàu xụ, mặt bằng chung lương của lập trình viên khá cao so với những ngành khác, lương 4-50tr là bình thường nhưng đó chỉ là lương tháng. Có nhiều lập trình viên theo nghề đã lâu, lương cũng cao nhưng đó không thể gọi là làm giàu được. Lập trình viên cũng chỉ là nhân viên, đi làm rồi nhận lương, nếu có bạn nào nuôi mộng làm giàu thì hãy tìm hiểu thêm về kinh doanh, mở công ty riêng.

Khó khăn V: Công việc buồn chán, dễ bị đau lưng

Các bạn trẻ mới bước vào nghề lập trình viên đôi khi sẽ không thể tránh khỏi những mộng mơ về ngành. Không phải Coder nào cũng có cơ hội để code ra Window, Facebook hoặc làm ra một app to như Grab. Đôi khi công việc của bạn chỉ là viết một chương trình nhỏ để nhận dữ liệu từ DB sau đó xuất thành file Excel với quy mô người dùng tầm 4-5 người…hoặc có thể chỉ là tạo ra BD, sau đó tạo thêm form, suốt ngày chỉ quanh quẩn với việc thêm form và xóa form, sửa trường này trường kia…công việc sẽ khá là nhàn hoặc có thể nói là nhàm chán, nó có thể bào mòn ý chí và mộng mơ của bạn. 

Lời khuyên để có thể đối mặt với khó khăn này chính là bạn hãy tìm ra sự đam mê, thú vị trong công việc và tận hưởng nó. Nếu các bạn đam mê một cái gì đó thì dù nó có tẻ nhạt ra sao thì bạn vẫn sẽ cảm thấy vui vẻ khi làm nó. Ví dụ: nếu công việc của bạn chỉ là viết ra một chương trình nhỏ để nhận dữ liệu từ DB rồi xuất thành file Excel thì bạn sẽ làm công việc của bạn trở nên thú vị hơn bằng cách cải thiện sao cho form đó xử lý thật nhanh, làm sao để sử dụng tiện hơn…

  Những góc khuất "đeo bám" người làm nghề lập trình

Ngoài ra các bạn cũng cần phải làm quen với việc công sức làm việc cực lực của bạn sẽ bị đem ‘đổ sông đổ biển’. Trong ngành này, việc 1 dự án đã tiến hành được 3-6 tháng mà vẫn bị hủy, dự án mà bạn ròng rã viết trong 6 tháng trời bỗng nhiên bị tạm dừng là điều hết sức thường xuyên xảy ra và đó cũng là thực trạng hiện nay trong nghề lập trình viên.

Bên cạnh đó, vì tính chất công việc nên nghề lập trình viên hầu hết ai cũng sẽ ngồi cả ngày nên sẽ dễ bị đau lưng, béo phì, thoái hóa cột sống…

Tóm lại nếu sau khi các bạn đọc bài viết này mà vẫn còn đam mê, có nghĩa là bạn đã sẵn sàng để dấn thân vào nghề lập trình rồi đấy. Bạn sẽ thấy việc học thêm về kiến thức công nghệ không có gì là ghê gớm, bạn sẽ thấy công việc áp lực là niềm vui, bạn sẽ thấy mức lương cao so với mặt bằng chung, bạn sẽ thấy việc nói chuyện với team, nói chuyện với máy tính là niềm vui chứ không phải sự tù túng. Chúc các bạn tìm được công việc phù hợp tại TopDev, vào link …. để có thể tham khảo thêm nhiều vị trí trong nghề lập trình nha!

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

TopDev tổng hợp

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

Những mã xấu mà Java 8 có thể khử

nhung-ma-xau-ma-java-8-co-the-khu

Bài viết được sự cho phép của Nguyễn Bình Sơn

Tới hiện tại, Java 8 đã được sử dụng trên hầu hết các ứng dụng chạy trên JVM, nhưng điều đó không có nghĩa là những gì tối tân của phiên bản này đã được khai thác triệt để. Dưới đây là một số cách viết mã già cỗi nên được cập nhật.

  10 câu hỏi JavaScript để tăng cường kỹ năng của bạn
  Giới thiệu về Reactive Programing trong javascript

1. Inner class vô danh

Bất cứ khi nào bạn gặp một inner class vô danh, bạn nên cân nhắc sử dụng biểu thức lambda. Lấy ví dụ:

list.sort(new Comparator()
  public int compare (String o1, String o2) {
    return o1.length() - o2.length();
  }
});

…chuyển thành như sau ngắn gọn hơn nhiều:

[java]list.sort((o1,o2) -> o1.length() - o2.length());

Dù vậy, mã ở đây vẫn không quá dễ đọc, chúng ta sẽ tiếp tục xem xét về Comparator.

2. Comparators

Comparator trong Java 8 không chỉ tối tân ở sự tương thích với các biểu thức lambda. Nó có những phương thức kết hợp với các tham chiếu phương thức, giúp cho mã trong sáng hơn rất nhiều:

[java]list.sort((o1,o2) -> o1.length() - o2.length());

Một ví dụ khác, bạn thậm chí có thể lấy các kết quả theo thứ tự ngược lại, tất cả chỉ bằng cách sử dụng thêm một phương thức hỗ trợ khác:

[java]list.sort((o1,o2) -> o1.length() - o2.length());

3. Các class không trạng thái

Thường thì bạn sẽ hay gặp các lớp không có gì khác ngoài các phương thức tĩnh (chúng thường được đặt tên được tận cùng là “Util” hay “Helper”), chúng có nhiệm vụ gom nhóm các phương thức lại trong một không gian tên duy nhất. Không ai cần phải tạo đối tượng của các class này, và kể cả khi có làm việc đó thì các đối tượng này cũng không lưu giữ bất cứ dữ liệu riêng nào, do đó các class này được gọi là class không trạng thái (stateless).

Với Java 8, các interface có khả năng chứa các phương thức tĩnh, và trở thành lựa chọn tốt hơn so với class, bởi chúng ta không phải lo có ai đó tạo đối tượng của interface. Ví dụ kinh điển lần nữa lại là Comparator – với các phương thức tĩnh hữu dụng và mạnh mẽ của nó.

Tương tự như thế, nếu bạn gặp một class trừu tượng không trạng thái, chỉ có duy nhất những phương thức trừu tượng được thiết kế để ghi đè, lớp đó có thể được chuyển đổi thành những FunctionalInterface và sau đó được implement bằng biểu thức lambda, như Runnable chẳng hạn:

Trước Java 8:

new Thread(new Runnable() {
    @Override
public void run() { 
      System.out.println("New thread created"); 
    } 
  }).start();

Java 8:

new Thread(() -> {
    System.out.println("New thread created");
}).start();

Một ví dụ khác để thử xem xét cách triển khai, sử dụng annotation @FunctionalInterface cho interface:

@FunctionalInterface
interface Square {
  int calculate(int x);
}

… và implement bằng biểu thức lambda:

int a = 5;
Square s = (x) -> x * x;
int ans = s.calculate(a);
System.out.println(ans);

4. Các chỉ dẫn lặp và rẽ nhánh lồng nhau

Chúng ta có bộ API Streams được thiết kế để truy cập các collection theo cách vô cùng uyển chuyển. Khi gặp mã nguồn như dưới đây:

List<Field> validFields = new ArrayList<Field>();
for (Field field : fields) {
  if (meetsCriteria(field)) {
    validFields.add(field);
  }
}
return validFields;

…bạn phải nghĩ tới việc thay thế bằng mã sử dụng Streams. Ở đây ta dùng filter và collect:

return fields.stream()
  .filter(this::meetsCriteria)
  .collect(Collectors.toList());

Đôi khi, các vòng lặp với một lệnh rẽ nhánh ở trong có thể được tái cấu trúc thành anyMatch hay findFirst:

for (String current : strings) {
  if (current.equals(wanted)) {
    return true;
  }
}
return false;

…có thể được thay thế bởi:

return strings.stream()
  .anyMatch(current -> current.equals(wanted));


Và:

for (String current : strings) {
  if (current.equals(wanted)) {
    return current;
  }
}
return null;

…có thể sửa thành:

return strings.stream()
    .filter(current -> current.equals(wanted))
    .findFirst()
    .orElse(null);

Lưu ý rằng orElse(null) thực tế là một mã xấu, chúng ta sẽ nói đến sau.

5. Đa thao tác trên collection

Mặc dù đã cố gắng tối ưu hóa, nhưng chúng ta vẫn thường xuyên gặp trường hợp một chuỗi các thao tác được thực hiện trên một hay nhiều collection để có được kết quả mong muốn. Xem xét ví dụ dưới đây:

// collect messages for logging
List<LogLine> lines = new ArrayList<>();
for (Message message : messages) {
  lines.add(new LogLine(message));
}
// sort
Collections.sort(lines);
// log them
for (LogLine line : lines) {
  line.log(LOG);
}

Chia để trị đã giúp cho mã được rõ ràng, nhưng chưa nói tới việc phải sử dụng tới comment để làm rõ ý, thì lời gọi Collections.sort vẫn gợi ý rằng chúng ta có thể sử dụng Streams tại đây. Trong thực tế, toàn bộ đoạn mã trên có thể được gộp vào một stream duy nhất:

messages.stream()
    .map(LogLine::new)
    .sorted()
    .forEach(logLine -> logLine.log(LOG));

Tái cấu trúc này không chỉ giúp mã dễ đọc hơn hay ít lại một biến trung gian, mà thực tế còn có hiệu năng cao hơn.

6. Duyệt để xóa bỏ các phần tử

Mã trước-Java-8 có thể có những đoạn mã như sau:

Iterator<String> iterator = strings.iterator();
while (iterator.hasNext()) {
  String current = iterator.next();
  if (current.endsWith("foo bar")) {
    iterator.remove();
  }
}

Giờ đây đoạn mã trên có thể được rút ngắn còn một dòng:

[java]list.sort((o1,o2) -> o1.length() - o2.length());[java]list.sort((o1,o2) -> o1.length() - o2.length());

Ngắn hơn, dễ đọc hơn, và cũng nhanh hơn!

7. Kiểm Null

NullPointerExceptions là điểm chí tử của các nhà phát triển Java, và bạn sẽ không lấy làm lạ khi các phép kiểm null nằm rải rác trong mã. Java 8 cho chúng ta API Optional giúp chúng ta mô tả kết quả trả về tốt hơn nhiều cũng như loại bỏ các kiểm null không cần thiết. Hãy quay lại với orElse mà chúng ta có ở tái cấu trúc số 4:

public static String findString (String wanted){
  List<String> strings = new ArrayList<>();
  return strings.stream()
      .filter(current -> current.equals(wanted))
      .findFirst()
      .orElse(null);
}

Bất kỳ lời gọi findString nào cũng sẽ phải kiểm null cho giá trị nhận được, và nếu an toàn thì làm một thao tác nào đó:

String foundString = findString(wantedString);
if (foundString == null) {
  return "Did not find value" + wantedString;
} else {
  return foundString;
}

Mã này xấu, dễ lặp và tẻ nhạt. Nếu cập nhật phương thức findString thành sử dụng Optional:

public static Optional<String> findString(String wanted) {
  List<String> strings = new ArrayList<>();
  return strings.stream()
      .filter(current -> current.equals(wanted))
      .findFirst();
}

…thì chúng ta có thể thoát khỏi trường hợp không có giá trị một cách thanh nhã hơn nhiều:

[java]list.sort((o1,o2) -> o1.length() - o2.length());

Bài viết gốc được đăng tải tại Tạp Chí Lập Trình

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

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

CTO là gì – Những sự thật cần biết về Chief Technology Officer 

cto-la-gi

CTO là gì? Luôn là một câu hỏi mà rất nhiều người trong giới lập trình hiện đang quan tâm. Michel Krieger (Instagram), Werner Hans Peter Vogels (Amazon) hay David Hasson (founder của Ruby on Rail) đều là những CTO tiêu biểu, những người tiên phong trong việc thay đổi thế giới bằng những ý tưởng công nghệ tiến bộ.

Lê Hồng Việt (FPT), Thái Trí Hùng (MoMo), Nguyễn Sơn Tùng (Việc Có) cũng là những Giám đốc công nghệ có tên tuổi tại Việt Nam, tạo nên sự đột phá công nghệ, đưa sản phẩm trong công ty họ lên một tầm cao mới.

Có thể thấy, với sự phát triển liên tục của ngành công nghệ thông tin trong những năm vừa qua, CTO không còn là vị trí quá mới lạ đối với cộng đồng IT. Thậm chí thuật ngữ này đã xuất hiện hơn chục năm rồi, vậy mà chúng ta vẫn còn bị nhầm lẫn với các chức vụ khác vì chưa thực sự hiểu rõ trách nhiệm của một CTO.

CTO không chỉ là “IT Director”

Chief Technology Officer – CTO là gì? 

Đôi khi, chúng ta hiểu nhầm rằng CTO chính là chức danh của anh chàng “lập trình viên sáng giá nhất phòng”. Tuy nhiên, sự thật thì bên cạnh giỏi về coding, CTO cũng phải nâng cao kỹ năng quản trị cũng như tầm hiểu biết sâu sắc về doanh nghiệp để tạo nên sợi dây liên kết bền vững với hội đồng quản trị.

5 Qualities of a Great CTO - ITChronicles

Bằng cách sử dụng công nghệ để giảm việc chi tiêu liên tục, tối ưu hóa quy trình, phân tích xu hướng thị trường và dự báo lợi nhuận, CTO đóng vai trò thiết yếu, giúp công ty giữ được lợi thế cạnh tranh và duy trì, phát triển công nghệ, kỹ thuật, hỗ trợ gia tăng doanh số. 

Đối với các startup, bạn cũng sẽ khó tìm thấy dòng mô tả công việc chính xác cho một CTO. Điều duy nhất bạn có thể chắc chắn là nhiệm vụ chính của CTO là cho phép công ty đạt được các chỉ tiêu doanh thu và marketing một cách tối ưu nhất thông qua việc sử dụng công nghệ tiên tiến.

Chia sẻ kinh nghiệm xương máu của một CTO nổi tiếng tại Việt Nam

Thời kỳ công nghiệp 4.0 tạo nên xu hướng kinh doanh đi kèm công nghệ thông tin, thúc đẩy mạnh mẽ nhu cầu tìm kiếm một CTO có năng lực cao. Trong năm 2020, mức lương cho vị trí này trên toàn cầu là khoảng 159,920 $ / năm, riêng các công ty blue chip như IBM và Boston Dynamics đề nghị mức lương trung bình hàng năm lên đến 200,000$.

Phân biệt CTO và CIO 

Vai trò giữa giám đốc thông tin (CIO) và giám đốc công nghệ (CTO) thường bị nhầm lẫn.Trước kia, CIO sẽ là người đảm nhận công việc của CTO nhưng vì công nghệ phát triển với tốc độ chóng mặt, số lượng công việc ngày càng tăng cao, nên vai trò của CTO và CIO được tách biệt để đảm bảo hiệu quả cho các hoạt động của công ty và CTO sẽ chỉ có một mối bận tâm duy nhất là phụ trách các vấn đề về mảng kỹ thuật cũng như công nghệ.

cto la gi

Đặc điểm giúp chúng ta dễ dàng phân biệt được nhất là CIO thường làm việc với nội bộ, tức cải thiện các quy trình trong công ty và là người quản lý cơ sở hạ tầng công nghệ hàng đầu.Trong khi đó, một CTO sẽ điều hành nhóm kỹ sư, đảm bảo chiến lược công nghệ của công ty phù hợp với các mục tiêu và yêu cầu đặt ra. Đặc biệt, vị giám đốc này còn là gương mặt đại diện của công ty tại các hội nghị, sự kiện thương mại để củng cố hình ảnh thương hiệu, truyền tải những cải tiến đột phá của sản phẩm/ dịch vụ đến công chúng. CTO thường báo cáo cho CIO, trong khi CIO báo cáo cho Giám đốc điều hành (CEO).

Một ngày làm việc của CTO

Có một thực tế là trách nhiệm của CTO trong công ty còn tùy thuộc vào nhiều yếu tố như phạm vi hoạt động, lĩnh vực hoạt động, chính sách phát triển kinh doanh, số lượng của nhân viên tại nơi làm việc hay nhân lực outsource, và nhiều yếu tố khác nữa. CTO có thể đảm nhiệm nhiều trách nhiệm khác nhau, không giống như các giám đốc điều hành cấp lãnh đạo khác như CEO hay CFO.

Ngoài ra CTO cũng có một số khó khăn nhất định mà không phải ai cũng hiểu 

Lựa chọn platform và thiết kế kỹ thuật

CTO luôn tham dự một cách trực tiếp hoặc gián tiếp vào toàn bộ các dự án liên quan đến kỹ thuật của công ty. CTO sẽ phụ trách cho việc lên kế hoạch, chiến lược, và chịu trách nhiệm triển khai ý tưởng trở thành hiện thực, đảm bảo duy trì tiến độ và năng suất cho dự án. Trong các công ty startup nhỏ, founder thường sẽ kiêm luôn công việc của CTO và tại các tập đoàn lớn, CTO sẽ điều hành một số team lập trình viên bao gồm những nhóm phục vụ nhu cầu công nghệ cho công ty.

Đôi khi, CTO có thể được gọi là một PM – Product Manager với mục tiêu chính là quản lý team kỹ thuật và đưa ra các quyết định quan trọng trong thực thi dự án như lập kế hoạch thiết kế công nghệ, bố trí kiến trúc sản phẩm và lựa chọn nền tảng phát triển.

Trong trường hợp team tech không có đủ kiến thức hoặc tài nguyên để hoàn thành task, thì CTO sẽ phải là người tìm ra giải pháp. Chính vì thế, họ phải là người có được nhiều kỹ năng đa dạng về công nghệ cũng như các kỹ năng mềm để xây dựng team mạnh.

Năm 2020, cũng giống như những người làm nhiệm vụ kỹ thuật, giám sát công nghệ và quản lý dự án, CTO với vai trò dịch vụ cũng được tăng mạnh khi các công ty chọn phương án outsource để tiết kiệm chi phí ngân sách cho các dự án.

Tham khảo thêm: Tuyển dụng việc làm CTO lương cao trong Developer.

Các vấn đề về MVP và DevOps

MVP với tên đầy đủ là Minimum Viable Product hay sản phẩm khả thi tối thiểu, là một sản phẩm có tính tăng thiết yếu được tạo ra để kiểm tra các giả thuyết marketing và phân tích phản hồi thực tế của người dùng. Có sự khác biệt khá lớn giữa vai trò và trách nhiệm của một CTO trong doanh nghiệp nhỏ và tập đoàn lớn về việc phát triển MVP.

Trong khi CTO của một doanh nghiệp đa quốc gia sẽ thuộc các cấp quản lý khác xa với việc chăm sóc kỹ thuật hàng ngày, CTO trong một công ty nhỏ cần phải lo liệu các tác vụ về tech thường sẽ lo luôn về phần iteration của sản phẩm đầu tiên. Backup quy trình công nghệ cũng rơi vào phần công việc của CTO, ngay cả khi họ có ngân sách lớn và có thể thuê thêm executive để thực thi các tác vụ liên quan đến phần MVP. 

Có thể thấy, trách nhiệm của một CTO có chút mơ hồ. Nhiệm vụ của kỹ sư DevOps cũng nằm trong danh sách công việc của họ. Đôi khi, họ còn phải xây dựng luôn phần tech của sản phẩm ngay từ lúc bắt đầu bao gồm các tính năng, tương tác máy chủ, script, map giai đoạn triển khai và SSH.

Tuyển dụng và quản lý sự tăng trưởng team

CTO có nhiệm vụ phỏng vấn và quyết định tuyển thêm người mới cũng như là quản lý team để tạo ra năng suất tối đa. Trong năm 2020, nhiệm vụ ngày càng trở nên khó khăn hơn cho các startup, cũng như thị trường nghề nghiệp dần được thắt chặt, các công ty kỹ thuật số tiếp tục tăng trưởng và yêu cầu nhiều nhân viên hơn. Các chuyên gia IT có xu hướng sẽ muốn chuyên về lĩnh vực mà họ cảm thấy thích hợp, trong khi các startup thường cần các người đa năng hơn trong mọi vấn đề mà công ty cần giải quyết.

  Lời khuyên từ Việt Trần - CTO DOF Hunt “Cách quản trị tốt nhất chính là không quản trị”

Một vai trò khác của CTO là lựa chọn lập trình viên – các team mate phù hợp.  Họ sẽ tiến hành giám sát quá trình onboarding để chọn lựa các ứng viên thích hợp. Chính vì thế, tìm hiểu thêm về các chiến lược tuyển dụng cũng được các CTO ngày nay quan tâm.

Trong những công ty lớn hơn, mô tả công việc CTO có thể bao gồm cả việc tổ chức các hoạt động đào tạo cho bộ phận công nghệ, hỗ trợ việc tự học và giám sát đội ngũ. Đó là lý do tại sao kinh nghiệm về quản lý sự kiện hay kỹ năng tư vấn, và có mối quan hệ rộng là một lợi thế khác biệt lớn trên CV của một CTO.

An ninh mạng

CTO sẽ làm gì bên cạnh việc quản lý bộ phận kỹ thuật? An ninh mạng là một vấn đề nữa mà họ phải chịu trách nhiệm. Các lỗ hổng bảo mật có thể xảy ra trong cơ sở dữ liệu của công ty, trong các trang web, hay bất kỳ tôl kỹ thuật số nào mà các team sử dụng. Các sản phẩm đang được phát triển bởi công ty cũng có thể yêu cầu các thuật toán bảo mật để giữ dữ liệu người dùng được riêng tư và mã hóa.

CTO sẽ là người phụ trách phát triển phương thức bảo mật, phát triển thuật toán, thực hiện kiểm toán cẩn cấp và nhiều hơn nữa. Các coder phải làm việc theo chỉ thị của CTO đặt ra.

  Big data là gì? Trò chuyện cùng CTO của Datamart Solutions để hiểu hơn về data

QA và thử nghiệm sản phẩm

Có chút khác biệt giữa mô tả công việc và nghĩa vụ của một CTO tại công ty startup. Các startup hiếm khi có một bộ phận đảm bảo chất lượng riêng biệt, có nghĩa là việc kiểm tra sản phẩm nên được phân chia giữa các lập trình viên và các thành viên khác của team. Trách nhiệm của CTO là quyết định ai sẽ là người chịu trách nhiệm cho quá trình debug. Và khi một bug kỹ thuật được tìm thấy, thường thì nó sẽ được chuyển tiếp tới CTO, người sau đó cần quyết định cách để giải quyết vấn đề đó. Công việc mà CTO có liên quan tới cũng có thể bao gồm các hướng dẫn được ghi chép cho việc fix bug cụ thể.

cto la gi

Trong các công ty tầm trung, CTO phải phát triển một hệ thống thử nghiệm các bản cập nhật và công cụ sắp tới để quan sát tiến trình. Hãy nhớ rằng CTO là một người vừa phải lo phần công nghệ vừa phải đảm nhiệm các lĩnh vực kinh doanh khác, nên hầu hết các câu hỏi liên quan tới việc quản lý QA và ngân sách kỹ thuật thường sẽ được gửi trực tiếp cho họ.

Lộ trình tăng trưởng và sự đổi mới sáng tạo

Vậy một CTO sẽ làm gì? Nói đơn giản, CTO nghĩ về tương lai, vạch ra nó, và rồi thực hiện kế hoạch theo từng bước. Trong giai đoạn khám phá dự án, CTO sẽ dựng lộ trình tăng trưởng, cân nhắc để các mục tiêu và chiến lược đó có thể hoạt động hiệu quả cùng nhau. CTO còn làm thủ công với nhiều khía cạnh khác nhau của một sản phẩm kỹ thuật số như lập trình, UX, bảo mật, ngân sách, quy trình vận hành và điều phối nhóm.

Bên cạnh việc triển khai MVP, CTO còn chịu trách nhiệm lên kế hoạch cho phiên bản sản phẩm tiếp theo và cập nhật công nghệ. Thông thường, họ sẽ hoàn tất các vai trò ngân sách liên quan với việc tái xây dựng MVP, nghiên cứu các phản hồi từ người dùng, hợp tác với các nhà khoa học dữ liệu và lấp vào các khoảng trống về phần tài nguyên. một chuyên gia với level này cần hiểu rõ với việc xử lý dữ liệu và bảo mật lưu trữ dữ liệu.

Trách nhiệm của CTO sẽ thay đổi ra sao với sự tăng trưởng của công ty?

Như các bạn đã thấy, CTO cần phải linh hoạt. Công ty càng lớn thì khả năng quản lý càng đòi hỏi cao hơn, vừa là người đứng đầu về kỹ thuật và đôi khi tự mình thực thi các tác vụ kỹ thuật.

Nhưng trách nhiệm chính của CTO vẫn là chăm lo cho mục tiêu thương mại của công ty bằng một đội kỹ thuật. Nói cách khác, một người ở vị trí này phải biết dự đoán tương lai và lên kế hoạch . CTO sẽ lên kế hoạch phát triển sản phẩm, tính toán ngân sách, quản lý team, triển khai sản phẩm, và đặt ra các quy trình làm việc khi xem xét việc update sản phẩm.

Nếu một CTO tại startup nhỏ làm tốt công việc của mình, công ty có thể phát triển nhanh chóng và vai trò của CTO sẽ thay đổi rõ rệt.

“Trình” thế nào thì có thể thành CTO?

Có một sự thật là công ty có quy mô càng lớn thì càng đòi hỏi CTO phải có nhiều kỹ năng mềm và kinh nghiệm quản lý dày dặn. Và sau đây là một số kỹ năng cần thiết dành cho một CTO:

Kỹ năng giao tiếp tốt

CTO phải lãnh đạo team code, phỏng vấn và quyết định ứng tuyển thêm newbie, cũng như khích lệ đồng đội cập nhật công nghệ mới và làm việc bằng các phương pháp mới. Đồng thời, CTO sẽ giao tiếp với các bộ phận khác như HR, các giám đốc cấp cao khác và đôi khi là cả khách hàng nữa.

Sáng tạo và nhanh nhạy trong giải quyết vấn đề

Khi công việc phát sinh vấn đề, CTO sẽ là người thông báo và đứng ra giải quyết. Nói cách khác, người đứng đầu kỹ thuật được kỳ vọng để phát triển và đưa ra các giải pháp như fix bug, thực thi tác vụ, hỗ trợ kỹ thuật. Mặt khác, họ cũng phải là những chuyên gia xử lý các vấn đề kỹ thuật mà không cần phải có sự hỗ trợ từ bên ngoài.

Khả năng lãnh đạo và cố vấn

Một CTO giỏi là người có thể ‘bán’ các ý tưởng chiến lược phát triển hoàn toàn mới, được vận hành bởi các công nghệ hiện đại và họ biết cách biến chúng trở thành hiện thực. Để tạo nên thành tựu thực tiễn, họ cần có khả năng truyền cảm hứng và thuyết phục mọi người về tính khả thi và những lợi thế. Người đứng đầu kỹ thuật cũng sẽ biết cách thúc đẩy sự phát triển của đồng đội – các tài năng có sẵn, săn được hay outsource.

Tự trau dồi kiến thức không ngừng

CTO ở các công ty vừa và nhỏ thường là những chuyên gia có kỹ năng về kỹ thuật tốt nhất trong team. Quy tắc này có thể thay đổi đối với các công ty hay tập đoàn lớn, nơi các CTO có nhiều nhiệm vụ liên quan tới việc quản lý hơn và ít nghĩa vụ tác nghiệp liên quan tới kỹ thuật hơn.

Tuy nhiên, có một điểm chung dù một CTO có làm ở bất kỳ đâu thì họ vẫn luôn là người có tầm nhìn kỹ thuật tốt nhất trong một công ty. Để duy trì trong ngành công nghiệp, họ cần phải khám phá các công nghệ, thậm chí là tạo ra những đột phá mới mẻ và cảm thấy thoải mái trong một môi trường chuyên nghiệp cấp cao.

Kỹ năng cập nhật xu hướng công nghệ

Tất nhiên, CTO cần phải cập nhật kiến thức chuyên môn liên tục nhằm đuổi kịp xu hướng công nghệ hiện đại. Xây dựng kiến trúc sản phẩm kỹ thuật số, MVP và lập trình API và test, quản trị hệ thống công nghệ cao của công ty, các kỹ năng DevOps – tất cả kỹ năng này bạn có thể tìm thấy khi đọc bảng mô tả công việc CTO trong nhiều công ty khác nhau. Bộ kỹ năng này sẽ được yêu cầu tùy vào quy mô và đặc thù công nghệ của mỗi công ty.

Có tầm nhìn và tư duy chiến lược

CTO phải dẫn đầu và lên kế hoạch cho phần tech full-stack. Họ phải tiếp cận để phát triển, có quy trình làm việc khoa học, và lập kế hoạch hay kiểm tra ngân sách dự án cùng với những người quản lý dự án cấp cao khác. Ngoài ra, một yếu tố quan trọng mà CTO cần có là quan sát được toàn bộ bức tranh ở nhiều cấp độ khác nhau: dự án, bộ phận, công ty để có thể xác định chiến lược công nghệ của công ty và đường lối phát triển. 

cto là gì

Kết luận

Như bạn đã thấy, trách nhiệm của CTO khó mà xác định được chỉ trong vài dòng chữ. Khá mà khó xác định chính xác rằng vị trí của người đứng đầu về công nghệ sẽ nằm ở đâu giữa thực hiện kỹ thuật và quản lý quá trình hoạt động.

“ Một CTO được kỳ vọng là người có các kỹ năng mềm và kỹ năng cứng vượt trội, cùng khả năng nắm bắt khoa học công nghệ thông tin xuất sắc.”

Bạn đã sẵn sàng để trở thành một CTO? – Một người tiên phong công nghệ trong tất cả các khía cạnh của doanh nghiệp, cân bằng nhu cầu của nhân viên, người dùng (hay khách hàng) và các bên liên quan có chung lợi ích. Tùy vào đặc thù của từng công ty, nhiệm vụ của CTO sẽ thay đổi. Xây dựng chiến lược tech, vấn đề an ninh, cố vấn cho các thành viên trong team, kiểm tra chất lượng, khám phá các xu hướng công nghệ mới và triển khai, nghiên cứu phản hồi, launching MVP, và tìm ra các giải pháp hiệu quả cho các khó khăn về phần kỹ thuật, v…v… chỉ là một số ví dụ phổ biến.

Nếu bạn có kế hoạch để ứng tuyển vị trí CTO cho bất kỳ công ty nào, hãy chuẩn bị một CV tập trung chính vào chuyên môn kỹ thuật và kỹ năng quản lý quy trình vận hành thật tốt.

Nếu công ty của bạn đang săn lùng một CTO tiềm năng, hãy đánh giá nhu cầu công nghệ hiện tại và tương lai của doanh nghiệp bạn.

TopDev tổng hợp.

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

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

Những áp lực lớn mà lập trình viên phải trải qua

ap-luc-cua-lap-trinh-vien

Bất kỳ ngành nghề nào, đặc biệt là nghề lập trình viên luôn có áp lực riêng mà ít ai hiểu được. Nếu bạn có nhiều trăn trở. Bài viết này sẽ chia sẻ chi tiết về những áp lực mà lập trình viên sẽ gặp phải khi theo ngành.

Áp lực từ sếp

Sếp là người đánh giá kết quả công việc và đồng thời cũng là người giao việc cho mình, do vậy áp lực từ sếp là rất lớn. Nếu may mắn gặp được những người sếp tốt, biết được trình độ mình đến đâu, thích làm việc gì, mình có điểm mạnh điểm yếu nào thì công việc của bạn sẽ rất nhẹ nhàng. Tuy nhiên, nếu các bạn gặp phải những người sếp khắt khe thì công việc sẽ rất mệt mỏi, có khi họ sẽ giao cho bạn công việc bạn không biết làm gì cả và bắt bạn tự học hoặc giao cho bạn một công việc bạn cực kì ghét.

Trong những trường hợp như vậy, các bạn không thể nào lơ sếp hoặc không nghe sếp được vì họ là sếp của mình, họ là người sẽ trả lương cho mình và đánh giá chất lượng công việc của mình. Vì vậy, trong trường hợp các bạn bị áp lực từ sếp thì nghỉ việc là cách đơn giản nhất, hoặc là trao đổi trực tiếp với họ hoặc trao đổi với những người sếp ở vị trí cao hơn để tìm ra cách giải quyết áp lực của mình.

Áp lực từ đồng nghiệp

Trong nghề lập trình, có 2 dạng áp lực từ đồng nghiệp:

lập trình viên

Dạng 1: Đồng nghiệp quá giỏi

Dạng này thường thấy ở các bạn nhân viên mới đi làm, trong quá trình làm các bạn nhận thấy đồng nghiệp trong công ty làm việc ‘quá nhanh, quá nguy hiểm’, họ rất giỏi và làm việc năng suất cao, họ biết nhiều thứ trong khi bạn không biết gì. Chính những lý do đó vô hình chung tạo thành áp lực cho bạn trong lúc làm việc.

Thực ra bạn không cần lo lắng quá nhiều vì dạng áp lực này, có thể không phải họ giỏi hơn bạn, chẳng qua họ đã có kinh nghiệm làm việc lâu hơn, họ nắm vững được công nghệ của dự án họ đang theo, nắm rõ những vấn đề trong dự án như thế nào. Có thể nói, họ giỏi là vì họ làm nhiều quen tay, lời khuyên tốt nhất ở đây chính là đừng bao giờ đem bản thân mình ra so sánh với người khác. Nếu bạn muốn trở nên giỏi như họ, bạn chỉ cần làm lâu như họ, nhận nhiều dự án làm giống họ, giao tiếp với họ…thì áp lực sẽ giảm đi nhiều lắm đấy!

Dạng 2: Xảy ra xung đột với đồng nghiệp

Mâu thuẫn trong chỗ làm là điều không thể tránh khỏi khi đi làm, đặc biệt, đối với những lập trình viên thì sự mâu thuẫn này càng gây gắt hơn. Nguyên nhân là do hầu hết những người theo ngành lập trình đều là con trai, do vậy khi các phương án giải quyết được đưa ra, họ luôn nghĩ mình là người đúng, ở họ có sự tự tin ngất trời và cái tôi cao. Do vậy khi làm việc chung với nhau rất dễ xảy ra mâu thuẫn dẫn đến cãi nhau, nghiêm trọng hơn có thể dẫn đến xung đột tay chân…

Lập trình viên mà cãi nhau thì không ai nhường ai cả, ai cũng nhận là mình đúng, do vậy chuyện xảy ra xung đột là không thể tránh khỏi. Đôi khi nguyên nhân dẫn đến xung đột chỉ là một vấn đề nhỏ nhưng cứ để trong lòng tích tụ theo từng ngày thì sự bất mãn sẽ trở nên to lớn dẫn đến việc mâu thuẫn không đáng có và cạch mặt nhau. Trong trường hợp các bạn làm chung với những đồng nghiệp ‘hổ báo’, giỏi mà không khiêm tốn hoặc là dở mà không biết khiêm tốn thì chắc hẳn các bạn sẽ gặp áp lực rất nhiều khi làm việc với những người như thế.

Developer là gì? Những kỹ năng cần có của một Developer
Lập trình viên

 

Lời khuyên trong trường hợp này là nghỉ việc hoặc đổi team, nhưng trong trường hợp bạn không muốn dễ dàng bỏ cuộc và xin nghỉ như vậy được thì cách tốt nhất vẫn là nhờ sếp vào cuộc hoặc là có 1 buổi nói chuyện ‘thân mật’ với nhau trên bàn nhậu. Emily và Bigdaddy có Hit ‘mượn rượu tỏ tình’ thì bạn cũng tranh thủ mượn rượu giãn hòa với đồng nghiệp đi nhé! Chỉ cần anh em rủ nhau đi nhậu, có gì ức chế thì mượn bia rượu nói hết ra là giải quyết xong ngay. Thực ra dân Dev có ưu điểm là không thù dai, nếu đã có người mở lời thì mâu thuẫn sẽ biến mất ngay thôi.

  "Mẹo bỏ túi" cho dân coder mới vào nghề
  Nghe Coder tâm sự chuyện tình buồn
  5 ví dụ chứng minh dân coder là những anh chàng vui tính nhất thế giới

Áp lực để theo kịp công nghệ

Loại áp lực thứ 3 mà nhiều bạn sẽ gặp phải đó là áp lực để theo kịp công nghệ, theo kịp ngành. Đối với ngành lập trình này thì kiến thức và công nghệ thay đổi liên tục, do vậy những ai không cập nhật công nghệ mới rất dễ bị đào thải khỏi ngành. Trước đây, Library rất hot nhưng giờ đây cũng ngày càng ít người dùng, họ chuyển qua các thư viện, các Framework khác hiện đại, tiện dụng hơn.

Chắc hẳn những việc này sẽ tạo thành áp lực cho các lập trình viên vì nếu không tự nâng cấp bản thân, cập nhật thông tin công nghệ thì kiến thức sẽ bị mai một. Cơ hội thăng tiến, cơ hội apply vào một công ty khác cũng theo đó mà biến mất là đều chắc chắn.Lời khuyên ở đây chỉ có 1, đó là tự thân vận động, nỗ lực tìm tòi học hỏi thêm nhiều kiến thức khi có nền công nghệ mới nào ra đời bằng cách lên các trang web công nghệ để đọc thêm thông tin sau đó thực hành, áp dụng thử 1 vài công nghệ mới trong một dự án nho nhỏ tự phát 1 mình hoặc cùng hội bạn lập trình.

lập trình viên

Bạn cũng có thể tự trang bị cho mình thêm những thứ nền tảng cơ bản khác…Chỉ có như vậy bạn mới không còn cảm thấy việc theo kịp công nghệ là gánh nặng, áp lực mà nó sẽ trở thành 1 thú vui và chỉ khi các bạn đã học vững kiến thức, vững nền tảng thì các bạn không còn sợ công nghệ mới nữa.

  CEO TopDev ra mắt công nghệ AI/Computer Vision trợ giúp kết nối doanh nghiệp với người mất việc vì Covid
  GraphQL - Công nghệ mới cho web developer

Áp lực từ dự án và công việc của lập trình viên

Áp lực cuối cùng đó là áp lực từ dự án và công việc mà mình gặp, đây là áp lực 100% lập trình viên nào cũng sẽ gặp phải. Khi các bạn tham gia vào một dự án mới, đôi khi các bạn sẽ gặp những vấn đề kiểu như ‘công nghệ này xa lạ quá mình không biết gì cả’, ‘dự án này phức tạp quá mình không làm được gì cả’ và đôi khi áp lực sẽ đến từ vấn đề deadline.

Những việc này tạo thành áp lực rất lớn vì khi deadline thì sếp sẽ là người hối thúc, bắt các bạn tăng ca làm việc đến 9-10h, thức đêm thức hôm và loại áp lực này sẽ không bao giờ giải quyết được trừ khi bạn hoàn thành được dự án. Do vậy, đối với trường hợp gặp áp lực như thế này thì chỉ còn cách ‘sống chung với lũ” thôi.

Tóm lại trong nghề lập trình viên này, áp lực loại nào rồi bạn cũng sẽ gặp, nhưng bạn cứ yên tâm rằng mọi chuyện rồi sẽ ổn thôi. Sau một thời gian dài làm việc bạn cũng sẽ có thêm kinh nghiệm và sẽ trở nên quen thuộc với các loại áp lực này, lúc đó bạn sẽ không còn sợ hãi nữa. Điều quan trọng nhất là bạn phải giữ gìn sức khỏe, đừng cảm thấy áp lực, bị stress rồi bỏ bê sức khỏe của mình nhé!

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

TopDev tổng hợp

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

5 kinh nghiệm khi viết arrow function

5-kinh-nghiem-khi-viet-arrow-function
Bài viết được sự cho phép của tác giả Lưu Bình An
Sử dụng arrow function đã quá phổ biến, ai cũng biết nó là gì, không cần một bài giới thiệu vài dòng nữa, bài viết này chia sẻ 5 kinh nghiệm để bạn làm việc với arrow function thêm mượt mà
  5 điểm khác nhau giữa function thường và arrow function
  Design Patterns là gì? Design patterns với Javascript thì có gì khác?

Gán tên cho arrow function

arrow function trong javascript là một anonymous (hàm không có tên), nếu gọi vào name của nó chúng ta sẽ nhận được một chuỗi rỗng

(number => number + 1).name; // => ''

Trong lúc debug hoặc phân tích call stack, hàm dạng anonymous rất khó chịu vì không biết đang chạy cái gì

Bên cột call stack có 2 function anonymous, không có bất kỳ thông tin nào được trích xuất ra cho chúng ta ở đây.

Nhưng nếu chúng ta khai báo một biến nắm giữ arrow function, Javascript lúc này lại ngầm hiểu nó là tên cho function đó (các đặc tính khác của arrow function không đổi)

const increaseNumber = number => number + 1;

increaseNumber.name; // => 'increaseNumber'

Lúc debug, nó đã hiện nguyên hình

Inline khi nào có thể

Thay vì phải viết một cách dài dòng

const array = [1, 2, 3];

array.map(number => {
  return number * 2;
});

Chúng ta có thể bỏ hẳn {} và return, ở dạng một expression

const array = [1, 2, 3];

array.map(number => number * 2);

Sử dụng với phép so sánh

Các phép so sánh <=>= nhiều khi dễ gây nhầm lẫn khi đứng chung với =>

const negativeToZero = number => (number <= 0 ? 0 : number);

Để không đánh đố người đọc, bọc nó lại trong dấu ngoặc đơn ()

const negativeToZero = number => (number <= 0 ? 0 : number);

//hoặc một cách tường minh
const negativeToZero = number => {
  return number <= 0 ? 0 : number;
};

Sử dụng với object literal

Nếu viết object literal như bên dưới chắc chắn bạn bị báo lỗi

const array = [1, 2, 3];

// throws SyntaxError!
array.map(number => { 'number': number });

Đừng quên thêm ngoặc đơn cho nó

const array = [1, 2, 3];

// Works!
array.map(number => ({ 'number': number }));

// có nhiều property
array.map(number => ({
  'number': number
  'propA': 'value A',
  'propB': 'value B'
}));

Hạn chế lồng nhiều arrow function

Thí dụ có một button, sau khi click chúng ta request lên server, sau khi nhận được giá trị, log xuống trình duyệt

myButton.addEventListener('click', () => {
  fetch('/items.json')
    .then(response => response.json());
    .then(json => {
      json.forEach(item => {
        console.log(item.name);
      });
    });
});

Viết vậy, thiên hạ chê khó đọc. Cân nhắc cách viết sau

const readItemsJson = json => {
  json.forEach(item => console.log(item.name));
};

const handleButtonClick = () => {
  fetch('/items.json')
    .then(response => response.json());
    .then(readItemsJson);
};

myButton.addEventListener('click', handleButtonClick);

Muốn ngon hơn là dùng async/await

const handleButtonClick = async () => {
  const response = await fetch("/items.json");
  const json = await response.json();
  json.forEach(item => console.log(item.name));
};

myButton.addEventListener("click", handleButtonClick);

Giới thiệu về Reactive Programing trong javascript

gioi-thieu-ve-reactive-programing-trong-javascript
Bài viết được sự cho phép của tác giả Lưu Bình An
Reactive programing là khái niệm khá trừu tượng và khó tiếp cận với người mới bắt đầu, chuẩn bị tinh thần đọc bài này vài lần trong vài ngày thì mới mong thẩm thấu hết.

Reactive programing là gì?

Reactive programming is programming with asynchronous data streams

Tạm dịch: Reactive programming là lập trình xử lý với dữ liệu không tuần tự (async) như stream

Có khái niệm mới stream

Muốn hiểu được reactive programing, bạn cần biết khái niệm stream

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

Stream là gì?

Có thể hình dung stream như là một array đặc biệt, chứa một tập các phần tử đặc biệt, các phần tử này có thể emit: 1. value, 2. error, 3. complete, các phần tử trong stream cũng không có hết ngay từ đầu, mà sẽ xuất hiện ở một thời điểm ko xác định trong tương lai.

Giới thiệu về Reactive Programing trong javascript

Về sau, mình dùng kiểu viết này để mô tả stream

--a---b-c---d---X---|->

a, b, c, d là các value được emit
X error
| completed signal
---> dòng thời gian

Tuân theo Observer Design Pattern, việc lắng nghe stream gọi là subscribe, những gì được emit, chúng ta viết các function để xử lý cho 3 trường hợp, các function này gọi là observer

Ví dụ, trên giao diện, chuỗi các event click trên một trang có thể được xem là một stream

Giới thiệu về Reactive Programing trong javascript

Trên stream click ban đầu, chúng ta thực hiện một số thao tác, nếu click trong khoảng 250ms gộp lại thành 1, filter để chỉ lấy các data lớn hơn 2. Những hàm để xử lý các data stream như vậy gọi là operator

Có rất nhiều thứ có thể xem là async data stream. Ví dụ: một cái form đăng ký với các input username, password, email, nút submit, nguyên quá trình user nhập giá trị các field này đến lúc submit, là một async data stream. Một giao diện counter, có duy nhất một button ấn để tăng counter, thì suốt quá trình ấn counter được xem là async data stream.

Để làm việc với Reactive Programing, 100% bạn cần dùng đến thư viện (siêu nhân có thể tự viết), tùy theo ngôn ngữ (ko chỉ có javascript mới có nhé), nó sẽ có một số hàm để bạn chuyển đổi một data bình thường thành một data stream (data stream là phải có thể emit 3 cái đã nói), một số hàm để bạn mergeflattenfilter các data stream này lại.

  JavaScript Arrays và Objects thật ra không khác gì sách và báo

Tại sao chúng ta cần Stream + Reactive Programing

Có thể thấy ngay Reactive programing khá trừu tượng, nhưng do thay vì implement những ràng buộc một cách chi tiết, những ràng buộc này được gắn vào từng data gửi đi trên stream, code nó sẽ gọn gàng hơn.

Kiểu viết này sẽ mang phong cách declarative hơn là imperative, chúng ta không khai báo từng bước tuần tự cần làm gì, chúng ta chỉ khai báo mối quan hệ giữa các stream với nhau.

Giới thiệu về Reactive Programing trong javascript

10 năm trước, mọi việc chỉ đơn giản là submit toàn bộ giá trị các field lên backend xử lý, rồi đơn thuần hiển thị kết quả trả về, bây giờ user thích real-time feedback, bấm “like” một phát là đầu bên kia thấy được liền.

Những event real-time như thế, user khoái, chúng ta cần có một công cụ lập trình để làm việc đó, Reactive Program ra đời cũng từ yêu cầu của user.

  JavaScript Executor trong Selenium Webdriver

Implement hộp thoại “Who to follow” của twitter

Mình sẽ sử dụng RxJS trong ví dụ, vì mình chỉ biết javascript thôi các bạn.

Giới thiệu về Reactive Programing trong javascript

Tính năng chính của hộp thoại này

  • Vừa mở lên, load data từ API, hiển thị 3 tài khoản
  • Click “Refresh”, hiển thị 3 tài khoản khác
  • Khi click “x”, xóa tài khoản đó khỏi danh sách, hiển thị một tài khoản khác.

Chúng ta tiếp cận với vấn đề này như thế nào, gần như mọi thứ có thể xem là stream.

Load dữ liệu lúc đầu

Bắt đầu với tính năng đơn giản nhất “Mới vào, load 3 account từ API”. (1) gửi 1 request (2) nhận response (3) render kết quả

Lúc bắt đầu chúng ta chỉ có 1 request, mọi thứ rất đơn giản, yên tâm là nó sẽ phức tạp dần lên khi có nhiều request. Mô phỏng nó như data stream, stream này chỉ có 1 emit value.

——a——-|—>

Khi có một event request xảy ra, nó báo 2 việc: khi nào và cái gì. Khi nào event này được emit và cái gì chính là value được emit (url string)

Trong Rx, bà con gọi stream là Observable, mình thích gọi là stream hơn

var requestStream = Rx.Observable.just('https://api.github.com/users');

Khi emit value, chúng ta subscribe để thực thi một hành động tiếp theo

requestStream.subscribe( requestUrl => {
// execute the request
  jQuery.getJSON(requestUrl, function(responseData) {
    // ...
  });
}

Cái response của request cũng là một dạng stream, dữ liệu sẽ đến tại một thời điểm không xác định trong tương lai

requestStream.subscribe(function(requestUrl) {
  // execute the request
  var responseStream = Rx.Observable.create(function (observer) {
    jQuery.getJSON(requestUrl)
    .done(function(response) { observer.onNext(response); })
    .fail(function(jqXHR, status, error) { observer.onError(error); })
    .always(function() { observer.onCompleted(); });
  });
  
  responseStream.subscribe(function(response) {
    // do something with the response
  });
}

Rx.Observable.create() sẽ tạo ra những stream mới, qua việc thông báo cho các observer đang subscriber các sự kiện onNext()onError().

Nó giống cách chạy của Promise lắm đúng không? Vâng Observable là một dạng Promise++, phiên bản mở rộng.

Chúng ta có 1 subscribe bên trong 1 subscribe khác, nó giống như callback hell. Thêm nữa việc tạo responseStream hoàn toàn độc lập với requestStream. Trong Rx chúng ta có một cách đơn giản để transform và tạo một stream mới từ những thằng khác

Hàm map(f), sẽ lấy từng giá trị của stream A, gọi function f(), và trả về giá trị cho stream B. Tạo một stream này từ stream khác, y như hàm map của array thôi mà.

var responseMetastream = requestStream
  .map(function(requestUrl) {
    return Rx.Observable.fromPromise(jQuery.getJSON(requestUrl));
  });

Sau đó chúng ta tạo một stream của stream metastream. Bắt đầu phức tạp rồi đó. Metastream là 1 stream mà mỗi cái value được emit sẽ trỏ ra 1 stream khác. Trong ví dụ, mỗi URL request, được trỏ đến một stream promise chứa response

stream của stream - metastream

Với responseStream, chúng ta chỉ một đơn giản một stream chứa response, nên việc tạo một metastream cho response sẽ rối và không cần. Mỗi giá trị được emit của response sẽ là một object JSON, không phải một Promise của object JSON. Sử dụng .flatMap() để gộp tất cả response thành 1 stream, .flatMap là operator để xử lý dữ liệu async trong Rx

var responseStream = requestStream
  .flatMap(function(requestUrl) {
    return Rx.Observable.fromPromise(jQuery.getJSON(requestUrl));
  });

flatMap để giảm số chiều của stream

responseStream được khai báo bởi requestStream, nếu sau này có thêm các sự kiện trên requestStream, chúng ta sẽ có một event response tương ứng trên responseStream

requestStream:  --a-----b--c------------|->
responseStream: -----A--------B-----C---|->

Sau khi có được responseStream, chúng ta render thôi

responseStream.subscribe(function(response) {
  // render `response` to the DOM however you wish
});

Toàn bộ bode bây giờ

var requestStream = Rx.Observable.just('https://api.github.com/users');

var responseStream = requestStream
  .flatMap(function(requestUrl) {
    return Rx.Observable.fromPromise(jQuery.getJSON(requestUrl));
  });

responseStream.subscribe(function(response) {
  // render `response` to the DOM however you wish
});

Nút refresh

JSON trả về từ API sẽ có 100 user, nó chỉ cho thêm offset, không cho set page size, chúng ta chỉ cần 3 user, lãng phí hết 97 user. Tạm thời không quan tâm phần này, chúng ta sẽ cache lại cái response sau.

Khi click nút refresh, requestStream sẽ emit một URL mới, sau đó chúng ta nhận được một response mới. Chúng ta cần 2 thứ:

  • 1 stream cho sự kiện click -> refreshStream
  • cập nhập lại requestStream để nó phụ thuộc vào refreshStream

RxJS có hàm để chuyển event thành stream

var refreshButton = document.querySelector('.refresh');
var refreshClickStream = Rx.Observable.fromEvent(refreshButton, 'click');

Click refresh nó không có URL kèm theo, chúng ta phải nhét cái URL bằng code. Map vào URL với giá trị offset ngẫu nhiên

var requestStream = refreshClickStream
  .map(function() {
    var randomOffset = Math.floor(Math.random()*500);
    return 'https://api.github.com/users?since=' + randomOffset;
  });

Tới đây, chắc chắn mở app lên không thấy gì cả, không có request nào được gửi đi, chỉ click refresh thì mới thấy.

Phải tách stream này ra riêng

var requestOnRefreshStream = refreshClickStream
  .map(function() {
    var randomOffset = Math.floor(Math.random()*500);
    return 'https://api.github.com/users?since=' + randomOffset;
  });
  
var startupRequestStream = Rx.Observable.just('https://api.github.com/users');

Sau đó mới .merge() lại

stream A: ---a--------e-----o----->
stream B: -----B---C-----D-------->
          vvvvvvvvv merge vvvvvvvvv
          ---a-B---C--e--D--o----->
var requestOnRefreshStream = refreshClickStream
  .map(function() {
    var randomOffset = Math.floor(Math.random()*500);
    return 'https://api.github.com/users?since=' + randomOffset;
  });
  
var startupRequestStream = Rx.Observable.just('https://api.github.com/users');

var requestStream = Rx.Observable.merge(
  requestOnRefreshStream, startupRequestStream
);

Có cách gọn hơn, không cần đến một stream trung gian

var requestStream = refreshClickStream
  .map(function() {
    var randomOffset = Math.floor(Math.random()*500);
    return 'https://api.github.com/users?since=' + randomOffset;
  })
  .merge(Rx.Observable.just('https://api.github.com/users'));

Thậm chí gọn hơn nữa

var requestStream = refreshClickStream
  .map(function() {
    var randomOffset = Math.floor(Math.random()*500);
    return 'https://api.github.com/users?since=' + randomOffset;
  })
  .startWith('https://api.github.com/users');

Chủ ý nãy giờ là giải thích .startWith() đó. Tuy nhiên là còn có thể tốt hơn nếu chúng ta không lặp lại URL. Làm việc đó bằng cách dời thằng startWith() ngay sau refreshClickStream, để giả lập sự kiện refresh khi vừa mới mở

var requestStream = refreshClickStream.startWith('startup click')
  .map(function() {
    var randomOffset = Math.floor(Math.random()*500);
    return 'https://api.github.com/users?since=' + randomOffset;
  });

Khi click nút refresh, chúng ta cũng sẽ remove 3 thằng user đang hiển thị, như vậy chúng ta sẽ subscribe trên refreshClickStream

refreshClickStream.subscribe(() => {
  // clear 3 sugesstion
})

Tuy nhiên, responseStream cũng đang có 1 subscribe ảnh hướng đến việc render, như vậy việc render này cũng tạo thêm 1 stream (có 2 sự kiện emit value để render)

var suggestion1Stream = responseStream
  .map(function(listUsers) {
    // get one random user from the list
    return listUsers[Math.floor(Math.random()*listUsers.length)];
  });

Chúng ta cũng sẽ có suggestion2Streamsuggestion3StreamsuggestionNStream hoàn toàn giống với suggestion1Stream, nhưng mình sẽ để các bạn tự suy nghĩ cách giải quyết. Ví dụ này chỉ đề cập đến suggestion1Stream

Thay vì render trên subscribe của responseStream

suggestion1Stream.subscribe(function(suggestion) {
  // render the 1st suggestion to the DOM
});

Quay lại vấn đề “click refresh, xóa suggestion”, chúng ta đưa vào sugesstion1Stream giá trị null khi refresh

var suggestion1Stream = responseStream
  .map(function(listUsers) {
    // get one random user from the list
    return listUsers[Math.floor(Math.random()*listUsers.length)];
  })
  .merge(
    refreshClickStream.map(function(){ return null; })
  );

Với trường hợp null, đơn giản render thông báo

suggestion1Stream.subscribe(function(suggestion) {
  if (suggestion === null) {
    // hide the first suggestion DOM element
  }
  else {
    // show the first suggestion DOM element
    // and render the data
  }
});

Hình dung quá trình này như sau, trong đó N là giá trị null

refreshClickStream: ----------o--------o---->
     requestStream: -r--------r--------r---->
    responseStream: ----R---------R------R-->   
 suggestion1Stream: ----s-----N---s----N-s-->
 suggestion2Stream: ----q-----N---q----N-q-->
 suggestion3Stream: ----t-----N---t----N-t-->

Click đóng một suggestion

Khi user click vào nút “x”, chúng ta sẽ load 1 user khác vào. Cách chúng ta nghĩ đến đầu tiên, tạo một request mới khi click vào nút “x”

var close1Button = document.querySelector('.close1');
var close1ClickStream = Rx.Observable.fromEvent(close1Button, 'click');

var requestStream = refreshClickStream.startWith('startup click')
  .merge(close1ClickStream) // merge với close stream
  .map(function(){
    var randomOffset = Math.floor(Math.random()*500);
    var 'https://api.github.com/users?since=' + randomOffset;
  })

Không chạy, nó sẽ remove user và tải mới 3 suggestion luôn. Vì cái API của chúng ta xài nó load 1 lần 100 user, nên giờ chúng ta chỉ lấy các user nào chưa hiển thị luôn, không cần refresh mới.

Suy nghĩ theo hướng stream, khi event close1 xuất hiện, chúng ta lấy emit response mới nhất trên responseStream, rồi lấy ngẫu nhiên 1 user

  requestStream: --r--------------->
   responseStream: ------R----------->
close1ClickStream: ------------c----->
suggestion1Stream: ------s-----s----->

Operator là combineLatest sẽ nhận vào 2 stream A, B, khi 1 trong 2 stream có emit value, combineLatest sẽ join 2 value emit gần nhất ab rồi trả về c = f(x, y), trong đó f là function chúng ta khai báo

stream A: --a-----------e--------i-------->
stream B: -----b----c--------d-------q---->
          vvvvvvvv combineLatest(f) vvvvvvv
          ----AB---AC--EC---ED--ID--IQ---->

Chúng ta có thể áp dụng combineLatest() cho close1ClickStream và responseStream, như vậy khi click nút close, nó sẽ lấy kết quả mới nhất từ response rồi trả về một giá trị mới cho suggestion1Stream

var suggestionStream = close1ClickStream
  .combineLatest(responseStream, function(click, listUsers) {
    return listUsers[Math.floor(Math.random()*listUsers.length)];
  })
  .merge(
    refreshClickStream.map(function() {return null;})
  )
  .startWith(null);

Còn vấn đề nhỏ xíu nữa là, combineLatest chỉ chạy khi cả 2 stream đã có giá trị, nếu 1 trong 2 stream chưa emit value nào hết, thì nó không chạy. Để giải quyết vấn đề này, chúng tả giả lập click close1 khi vừa mở app

var suggestion1Stream = close1ClickStream.startWith('startup click') // we added this
  .combineLatest(responseStream,             
    function(click, listUsers) {l
      return listUsers[Math.floor(Math.random()*listUsers.length)];
    }
  )
  .merge(
    refreshClickStream.map(function(){ return null; })
  )
  .startWith(null);

Tổng kết

Toàn bộ code

var refreshButton = document.querySelector('.refresh');
var refreshClickStream = Rx.Observable.fromEvent(refreshButton, 'click');

var closeButton1 = document.querySelector('.close1');
var close1ClickStream = Rx.Observable.fromEvent(closeButton1, 'click');
// and the same logic for close2 and close3

var requestStream = refreshClickStream.startWith('startup click')
  .map(function() {
    var randomOffset = Math.floor(Math.random()*500);
    return 'https://api.github.com/users?since=' + randomOffset;
  });

var responseStream = requestStream
  .flatMap(function (requestUrl) {
    return Rx.Observable.fromPromise($.ajax({url: requestUrl}));
  });

var suggestion1Stream = close1ClickStream.startWith('startup click')
  .combineLatest(responseStream,             
    function(click, listUsers) {
      return listUsers[Math.floor(Math.random()*listUsers.length)];
    }
  )
  .merge(
    refreshClickStream.map(function(){ return null; })
  )
  .startWith(null);
// and the same logic for suggestion2Stream and suggestion3Stream

suggestion1Stream.subscribe(function(suggestion) {
  if (suggestion === null) {
    // hide the first suggestion DOM element
  }
  else {
    // show the first suggestion DOM element
    // and render the data
  }
});

Sample có thể vọc ở http://jsfiddle.net/staltz/8jFJH/48/

https://gist.github.com/staltz

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

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

Cập nhật thông tin tuyển dụng IT – Lập trình viên tháng 7/2021

Dev cần làm gì để được săn đón

Hậu công cuộc dịch bệnh đã hầu như được kiểm soát tại Việt Nam và các công ty đã có thể khởi động lại các dự án của mình. Tuy nhiên, một trong những hệ lụy lớn và cũng được xem là vấn đề nan giải đối các công ty chính là sự thiếu hụt về nguồn nhân lực một cách trầm trọng. Vậy làm cách nào để các tổ chức/ doanh nghiệp có thể tái hoạt động tuyển dụng IT sau Covid? Cùng TopDev theo dõi các thông tin Tuyển dụng mới nhất tháng 7/2021.

Ra mắt gói Tuyển IT giá ưu đãi cho doanh nghiệp vừa & nhỏ kết hợp Đánh giá ứng viên IT

Mới đây nền tảng tuyển dụng IT TopDev (Top Developers) vừa cho ra mắt các gói tuyển dụng IT – Tuyển dụng lập trình viên chỉ từ 3.590.000 – giá tối ưu nhất trong năm 2020, với các ưu đãi và quyền lợi như sau:

tuyển dụng IT tuyển dụng IT tuyển dụng IT cấp tốc tuyển dụng IT topdev

ĐĂNG TUYỂN GÓI TÌM ỨNG VIÊN TẠI ĐÂY

Chưa kể mới đây, TopDev vừa tích hợp cùng hệ thống đánh giá ứng viên hàng đầu trên thế giới mang tên HackerRank – Nền tảng testing code lớn nhất thế giới với hơn 11 triệu coder toàn thế giới đang thực hành code và kiểm thử bởi các công ty công nghệ hàng đầu trên thế giới.

  • Bằng cách cho phép các nhà tuyển dụng mảng công nghệ và các nhà quản lý tuyển dụng đánh giá khách quan các nhân tài ở mọi giai đoạn của quy trình tuyển dụng, HackerRank giúp các công ty tìm kiếm các lập trình viên lành nghề và giúp họ đổi mới nhanh hơn. 
  • Đơn vị nổi tiếng với việc kết hợp các lập trình viên với các công ty tuyệt vời và hữu ích cho cả công ty và nhân viên, với hơn 7 triệu lập trình viên tham gia trang web này. 

Với đặc thù tuyển dụng khó khăn của ngành IT, chúng ta đều hiểu rằng cách tốt nhất để tìm được ứng viên mới đó là phải trực tiếp test kỹ năng quan trọng nhất của vị trí đó, chưa kể là thông qua những phần kiến thức cơ bản để giúp nhà quản lý nhanh chóng biết được ứng viên có phù hợp và đủ khả năng làm việc cho doanh nghiệp của mình hay không, giảm thiểu được rủi ro tối đa trong quá trình sàng lọc ứng viên.

tuyển dụng IT topdev

Tìm hiểu về TopDev X HackerRank – Hệ thống tích hợp Tuyển dụng và Đánh giá ứng viên IT đầu tiên tại Việt Nam

Đừng bỏ lỡ: Hoàn thiện quy trình đánh giá ứng viên IT cho nhà tuyển dụng 2020

Khi câu chuyện tuyển dụng IT không chỉ còn ở “Thông báo tuyển dụng”

Có thể ứng viên thấy mẫu tin đăng của bạn trên MXH, thế nhưng bạn đâu chỉ là duy nhất. Cả trăm ngàn cái doanh nghiệp IT khác cũng đang chạy nước rút trong cuộc đua tìm kỹ sư – người tài về đội IT.

Cái mà nhận sự IT và doanh nghiệp đang hướng đến lúc này đó là “để lại dấu ấn riêng trong cộng đồng kỹ sư – lập trình viên“.

Có thể các lập trình viên sẽ biết đến công ty qua một bài Facebook post, sau đó sẽ gặp chúng ta tại buổi Career talk hoặc workshop sharing, hoặc họ nghe một video bài nói chia sẻ của một Manager / Senior Developer của công ty bạn trên các kênh sharing và công nghệ (TopDev blog, Tech talk..) và sau đó tìm kiếm thông tin về chúng ta qua chính website tuyển dụng của công ty hoặc các trang đăng tin tuyển dụng IT nói chung. TopDev hiện sở hữu và liên kết với hơn 80% các kênh ngách dành cho lập trình viên, giúp các nhà tuyển dụng có thể phủ truyền thông một cách hiệu quả nhất.

  Các nguyên tắc 5W1H – 5W2H – 5W1H2C5M

Bên cạnh gói tuyển dụng giá rẻ SME, TopDev còn cho ra mắt gói tuyển dụng Enterprise với ưu đãi duy nhất trong tháng 7 như sau:

Lợi ích đăng tin

  • Nhận nguồn CV tự nhiên từ website TopDev & các website công nghệ liên kết của TopDev
  • Nhận nguồn CV giới thiệu từ TopDev
  • Được làm mới mỗi 10 ngày
  • Tin đăng được tô đỏ

Lợi ích Employer Branding

  • Email marketing đến 7.500 data đúng đối tượng
  • Ưu tiên hiển thị trong các kết quả tìm kiếm liên quan
  • Logo công ty được ưu tiên hiển thị tại mục Highlight Companies trên trang chủ TopDev
  • Đặc biệt, trải nghiệm gói HackerRank đánh giá ứng viên trị giá $100/ gói

tuyển dụng IT giá rẻ

DUY NHẤT TRONG THÁNG 7 – ĐĂNG KÝ NHẬN ƯU ĐÃI NGAY

Ở thời điểm hiện nay, có hơn 450 công ty đã cùng TopDev thực hiện Employer branding theo cách thức nêu trên, các Tech leads sẽ tham gia vào các sự kiện cộng đồng do TopDev tổ chức, hay xuất hiện trên những bài viết chuyên sâu được TopDev đăng tải trên các kênh ngách của ngành lập trình. Từ đó, các nội dung, hình ảnh, video này sẽ giúp các công ty lập trình viên hiểu hơn về các công nghệ, và tăng tỷ lệ apply một cách đáng kể.

Các chương trình của TopDev đã và đang làm sẽ giúp cho đội ngũ nhân sự hoạch định chiến lược quảng bá và xây dựng hình ảnh một cách chuyên nghiệp và đúng angle mà chỉ có những người trong ngành mới hiểu, từ đó giúp công ty quảng bá văn hoá Employer Branding của mình một cách dễ hiểu và trực quan nhất đến với các bạn lập trình viên. Với nhiều khách hàng lớn TopDev từng làm việc như FE Credit, VNG, KMS, v.v… tỷ lệ chuyển đổi và apply của họ tăng mạnh thậm chỉ là 200% nếu làm đúng cách và đúng thời điểm, giúp các anh chị HR hoàn thành sớm KPI tuyển dụng của năm.

Về nền tảng kênh tuyển IT TopDev – Top Developer :

cộng đồng it

Hệ sinh thái TopDev.vn

Sau gần 5 năm hoạt động, TopDev đã trở thành:

  • Nền tảng tuyển dụng CNTT hàng đầu tại Việt Nam với hơn 2.000 khách hàng và hơn 300.000 hồ sơ Developer.
  • Đơn vị duy nhất tại Việt Nam giúp xây dựng Thương hiệu Nhà tuyển dụng cho hàng trăm công ty CNTT tại Việt Nam.
  • Đơn vị uy tín nhất xuất bản các phân tích và báo cáo thị trường CNTT & nhân lực IT tại Việt Nam.
  • Đơn vị tổ chức của hai sự kiện Công nghệ có ảnh hưởng nhất tại Việt Nam: Vietnam Mobile Day & Vietnam Web Summit

Trong thời điểm chuyển giao nửa năm còn lại, doanh nghiệp nào cũng cần kết nối và nhanh chóng đưa hình ảnh một IT Employer lành mạnh đến với cộng đồng Lập trình viên Việt Nam và hỗ trợ ứng viên IT trên con đường phát triển sự nghiệp.

Hệ sinh thái TopDev gồm các chuyên trang website và Facebook fanpage hiện phủ khắp cộng đồng IT Việt Nam với gần 95% Lập trình viên đang sử dụng một sản phẩm của TopDev.

Để làm được điều đó không thể thiếu sự đồng hành của hơn 2.000 khách hàng –  là các công ty tập đoàn công nghệ hàng đầu tại thị trường Việt Nam như VNG, Tiki, Sendo, KMS Technology,… đều cũng chung 1 sứ mệnh – tìm được nhân tài IT đồng hành cùng các sản phẩm công nghệ Việt.

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

  Bí quyết phát triển hoạt động nhân sự qua email (Email Marketing) hiệu quả - Bạn đã biết?

  Tái tuyển dụng IT hiệu quả? Thách thức và cơ hội cho các công ty hậu Covid-19

OKR là gì? Kinh nghiệm xây dựng OKR hiệu quả

OKR

OKR là gì? OKR (Objectives and Key Results), thuật ngữ này được chuyển dịch với tên gọi Quản trị theo Mục tiêu và Kết quả then chốt. OKR được xem là một phương pháp quản trị giúp doanh nghiệp gắn kết mục tiêu cụ thể với kết quả chung của một tổ chức, tập thể lớn.

Với khả năng ứng dụng cao và quá trình hợp thức đơn giản phù hợp với xu hướng phát triển mới, OKR được nhiều tập đoàn, doanh nghiệp lớn sử dụng vào hệ thống quản lý của mình đặc biệt là các công ty về công nghệ: Spotify, Twitter, LinkedIn,… Thế nhưng, phạm vi hoạt động của OKR còn được mở rộng hơn nhờ sự tin dùng của các công ty từ nhiều lĩnh vực khác nhau: Walmart, The Guardian, ING Bank,…

Việc áp dụng OKR mang lại lợi ích gì cho doanh nghiệp?

Để áp dụng OKR hiệu quả, doanh nghiệp cần phải có một định hướng rõ ràng về những gì cần phải thực hiện. Hệ thống Quản trị này bao gồm 1 mục tiêu (Objective) – tức thứ doanh nghiệp cần đạt được và 5 kết quả cụ thể (Key result) – các kết quả này có thể được xác định và đo lường nhằm đạt được mục tiêu đề ra.          

OKR

Điều gì khiến OKR trở nên nổi bật?

OKR tập trung vào vấn đề tạo sự liên kết trong tổ chức và đó là lợi ích được người sử dụng đánh giá cao. Ngoài ra, một điểm cộng hoàn hảo là OKR đảm bảo tất cả mọi người đi cùng một hướng, với các ưu tiên rõ ràng, tạo sự nhịp nhàng cho quá trình diễn tiến hoạt động, từ đó gia tăng tính hiệu quả về chất lượng công việc.

Lợi ích của phương pháp này là giúp nhân viên trong công ty xác định đâu là ưu tiên cần thực hiện, từ đó tập trung sức lao động vào những mục tiêu có thể đo lường được, không sa đà vào những công việc không có giá trị, giúp giảm thiểu những rào cản trong vấn đề quản lý hiệu suất lao động. Tỷ lệ để đánh giá mức độ thành công của 1 OKR không nhất thiết phải đạt tới 100% trong ngắn hạn. Việc đạt được phần lớn mục tiêu (khoảng 70 – 80%) đã được coi là thành công.

Cụ thể, OKR mang lại cho doanh nghiệp những giá trị như sau:

  • Định hình chiến lược giúp quản lý hiệu suất lao động: OKR là thước đo chuẩn xác nhất giúp nhà quản trị định hướng mục tiêu, vạch ra những bước đi cụ thể trong việc định hình và phát triển chiến lược, Đồng thời, nhiều nghiên cứu đã chỉ ra rằng: Nhóm nhân viên áp dụng OKR trong công việc đem về cho doanh nghiệp lợi nhuận cao hơn, có hiệu suất lao động tốt hơn nhóm không áp dụng. Trên thực tế, nhiều nhân viên mong muốn doanh nghiệp mình sử dụng OKR trong tương lai.
  • Tác động tích cực làm “thay màu” văn hóa doanh nghiệp: Lợi ích lớn nhất của OKR là sự tác động mạnh mẽ vào văn hóa của doanh nghiệp, có tác động làm dịch chuyển lối tư duy từ quản trị thông qua KPI thuần túy sang việc hoàn thành mục tiêu trong công việc. Việc đề cao tính chuyên môn, sáng tạo dựa trên sự minh bạch chính là kim chỉ nam quan trọng mà OKR 
  •  Sự gắn kết: OKR ngày càng được nhiều doanh nghiệp lựa chọn vì không chỉ đảm bảo về hiệu quả quản trị mà còn giúp tạo ra một sự gắn kết giữa các nhân viên với chính doanh nghiệp của mình. Bản chất OKR là một mô hình quản trị vừa tác động đến sự vận hành hoạt động, vừa giúp nhân viên nhận ra mọi điều mình làm đều hàm chứa một ý nghĩa nhất định đối với sự phát triển chung của tổ chức.

  4 cách thúc đẩy sự phát triển nhân viên tại công ty

Các bước áp dụng OKR trong doanh nghiệp

OKR

Trước khi bắt tay vào việc áp dụng OKR vào quản trị doanh nghiệp, bạn cần phải có cái nhìn chính xác về những khó khăn mà mình đang mắc phải. Nó cách khác, bạn đang muốn doanh nghiệp mình đạt được mục tiêu gì trong tương lai.

Bạn có thể coi OKR là một trường phái với một hiệu suất quản lý hiệu quả. Có 2 bước hay 2 giai đoạn cần phải quan tâm: Giai đoạn đầu chuẩn bị chiến lược, sau đó là áp dụng thực tế.

Thiết lập cơ cấu quản trị OKR trong doanh nghiệp

Thông thường, người ta thường thiết lập chương trình OKR theo 2 nhóm đối tượng độc lập, phân mốc thời gian riêng biệt theo năm và theo quý. Mục tiêu doanh nghiệp có thể thực hiện hàng năm để thuận lợi cho việc đánh giá mức độ hiệu quả.

Với mỗi phòng ban, mục tiêu có thể được review theo từng quý để linh hoạt thay đổi chiến lược sao cho phù hợp với mục tiêu tổng thể của doanh nghiệp.

Bắt tay xây dựng chiến lược OKR

  • Xây dựng tầm nhìn và sứ mệnh: Một lời khuyên hữu ích cho mọi doanh nghiệp là cần xác định rõ 2 khái niệm tầm nhìn và sứ mệnh, tránh mơ hồ hoặc nhầm lẫn với nhau. Lưu ý, tầm nhìn và sứ mệnh phải đảm bảo được tính dài hạn. Điều này cho thấy khả năng lãnh đạo của những người đứng đầu doanh nghiệp. 
  • Xác định OKR cụ thể: Để xác định OKR cho toàn thể doanh nghiệp, bạn nên tổ chức một buổi họp nơi mọi ý kiến của nhân viên đều được thu thập và tôn trọng. Những ý tưởng khả thi nhất sẽ được lựa chọn, số lượng OKR lý tưởng của các công ty có thể áp dụng vào thực tế nên rơi vào tầm từ 3 đến 5 OKR.

Triển khai thực hiện OKR thế nào để đạt hiệu quả?

Như chia sẻ vào đầu bài viết, OKR là Quản trị theo Mục tiêu và Kết quả then chốt. Vì vậy, ta cần thiết lập các mục tiêu và các kết quả theo chốt để OKR được triển khai một cách hiệu quả.

Mục tiêu là những mô tả định tính về những điều doanh nghiệp muốn đạt được, các mục tiêu này giúp doanh nghiệp đi đúng hướng để đạt được kết quả mong muốn. Và đặc biệt, đây phải là những mục tiêu thực tế, có tính khả thi. Việc đặt ra thời gian hoàn thành mục tiêu để dễ dàng kiểm soát tiến độ cũng là một điều quan trọng. Hãy đặt câu hỏi như: “Ưu tiên quan trọng nhất hiện tại của doanh nghiệp là gì?” để khai thác điều doanh nghiệp mong muốn tìm kiếm hoặc còn thiếu sót, từ đó bắt đầu đề ra những mục tiêu cụ thể hơn. 

Các kết quả then chốt sẽ đi kèm với các mục tiêu đã chọn. Mỗi mục tiêu nên có từ 3 đến 4 kết quả then chốt để hỗ trợ đo lường quá trình hoàn thành các mục tiêu. Ví dụ trong việc đo lường hiệu quả năng suất lập trình, việc đưa ra các kết quả gắn với mỗi mục tiêu là điều rất quan trọng. Điểm quan trọng nhất của các kết quả then chốt chính là đảm bảo chúng là các mục tiêu định lượng, hoặc là những kết quả có thể đo lường được qua số liệu. Key result là những yếu tố giúp xác định sự thành công hoặc thất bại trong việc hoàn thành các mục tiêu đã đặt ra. 

Hãy giả sử một mô tả sau đây để lý giải quá trình. Nếu xem mục tiêu là điểm đến, tức mục tiêu cần đạt được, kết quả then chốt là con đường, thì cách triển khai là phương tiện để chúng ta có thể đi đến đích đến cuối cùng.

Bảng tổng hợp sau đây sẽ cho thấy những tính chất cần có trong mỗi thành tố: 

Mục tiêu Kết quả then chốt Cách thức
Tính chỉ dẫn v
Sự sắp xếp để đi đúng hướng v
Sự tác động mạnh v v
Tham vọng v
Đo lường được v v
Sự truyền cảm hứng v
Sự rõ ràng v
Sự cụ thể v v
Trong tầm kiểm soát v
Trong phạm vi ảnh hưởng của bạn v v v
Đúng trong khoảng thời gian giới hạn v v v
Số lượng 1-4 1-5 tối thiểu 1

Cuối cùng, bạn cần nhớ rằng việc triển khai OKR sao cho hiệu quả không chỉ phụ thuộc vào hệ thống quản trị mục tiêu mà còn cần đến kỹ năng lãnh đạo xuất sắc từ nhà quản lý. Đó không những là việc giỏi chuyên môn, quản trị mục tiêu và kết quả kỳ vọng tốt… mà còn là việc truyền cảm hứng và định hướng cho đội ngũ của mình bằng cách áp dụng các khía cạnh của trí tuệ cảm xúc (EQ).

>>> Xem thêm: Điều gì làm nên một nhà lãnh đạo thực thụ trong quản lý dự án?

Ví dụ cụ thể về OKR – bài toán xác lập hệ giá trị quan trọng trong Quản trị

Bước đặt mục tiêu – Objective

  • Trở thành doanh nghiệp dẫn đầu thị trường về tuyển dụng Nhân sự IT.
  • Ra mắt thành công giải pháp phỏng vấn video giúp xử lý hàng trăm ứng viên mỗi ngày.
  • Tạo ra nhiều doanh thu hơn so với cùng kỳ năm ngoái.

Lập kết quả then chốt – Key result

  • Test hiệu quả của dòng sản phẩm ứng dụng đạt 99% tiêu chí đề ra.
  • Giá trị của doanh nghiệp đạt ở mức cao.
  • Chốt được 3 – 5 hợp đồng lớn từ các đối tác là các tổ chức/doanh nghiệp cần nguồn cung ứng nhân sự IT phù hợp.
  • Phát triển thành công giá trị thương hiệu của doanh nghiệp bằng cách có từ 2 – 3 tờ báo lớn thông tin về tổ chức thông qua kế hoạch truyền thông.

Mô tả về cách thức cần phải triển khai thực hiện

  • Thuê nhân sự phụ trách quản lý vấn đề phát triển ứng dụng giải pháp phỏng vấn video.
  • Chạy các chiến dịch PR, social tùy vào mục tiêu đề ra
  • Xây dựng kịch bản liên hệ các khách hàng, đối tác liên doanh.

Lời kết

OKR là một phương pháp hữu hiệu và ngày càng được nhiều tổ chức/doamh nghiệp áp dụng vào mô hình hoạt động nhân sự và vận hành hoạt động của mình. Tùy vào quy mô và tuổi đời của từng doanh nghiệp, các nhà quản lý nhân sự cần có cách thức ứng dụng sao cho phù hợp nhằm hướng đến hiệu quả cao nhất.

Việc triển khai OKRs cần có sự tham gia, căn chỉnh giữa các cấp quản trị và nhân viên một cách đồng bộ. Một trong những cách giúp các nhà lãnh đạo, nhà quản trị nhân sự có kiến thức chuyên sâu trong việc thiết lập, triển khai OKR là tham gia khóa học OKR uy tín. Từ đó, doanh nghiệp có thể áp dụng thành công OKR vào thực tiễn và nhận được những giá trị từ phương pháp này.

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

Xem thêm việc làm it lương cao hàng đầu tại TopDev

Bí quyết tuyển lập trình viên – ứng viên IT thành công trong nửa cuối năm

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

Theo thông tin được cập nhật về thị trường IT mới nhất của TopDev, hiện nay có đến 62% ứng viên IT bị động, gấp gần 5 lần số lượng ứng viên chủ động tìm việc chỉ với 14%. Xu hướng này đã gây ra nhiều trở ngại cho các HR khi tuyển lập trình viên, đòi hỏi họ phải ngày một chủ động hơn trong việc tìm kiếm nhân tài. Chủ động hơn đồng nghĩa với việc các nhà tuyển dụng phải nỗ lực hơn, đầu tư nhiều thời gian để tìm kiếm và thu hút kiểu ứng viên này.

Nào hãy cùng TopDev tìm hiểu kĩ về ứng viên IT bị động, các ưu khuyết điểm, cũng như các biện pháp thực tiễn và chi tiết để cải thiện các vấn đề phát sinh từ kiểu ứng viên khó nhằn này nhé!

Ứng viên IT bị động là gì?

Ứng viên IT bị động – nôm na là những ứng viên IT không chủ động tìm việc nhưng được các nhà tuyển dụng chủ động tìm kiếm để lấp đầy cho các vị trí trống. Nói cách khác, họ không hề chủ động nộp CV ứng tuyển, mà chính những người tuyển lập trình viên mới là người tìm kiếm thông tin liên lạc và trực tiếp mời họ ứng tuyển.

Như bạn có thể thấy hiện nay có hơn 2/3 ứng viên IT khảo sát là ứng viên bị động, trong khi ứng viên chủ động chỉ dừng lại ở con số hạn chế 14%. Nói tới đây, bạn có thể thắc mắc kiểu ứng viên này có gì đặc biệt khiến cho mọi đội ngũ tuyển dụng phải “cuống cuồng” lên tìm kiếm? Cùng TopDev tìm hiểu kĩ hơn về điểm mạnh yếu của ứng viên IT bị động nhé!

Tại sao nên nhắm vào ứng viên IT bị động?

Nguồn ứng viên đếm không xuể

Hiển nhiên là số người không quan tâm vị trí công việc của bạn gấp nhiều lần người quan tâm, tỉ lệ này cũng na ná khi bạn đăng một ảnh lên Instagram, số người like chắc chắn sẽ thấp hơn nhiều số người theo dõi bạn! Hãy nhớ rằng bất kì ai trong độ tuổi lao động ngoài kia đều có thể là những nhân tài tiềm năng góp phần không hề nhỏ cho doanh nghiệp.

Quan trọng hơn là để việc vận hành doanh nghiệp lâu dài, tiếp cận những ứng viên IT bị động là không thể tránh được, như số liệu TopDev đề cập ở trên, chỉ với 14% ứng viên trong thị trường là chủ động tìm đến những HR tuyển lập trình viên, theo dõi website của bạn thường xuyên, thì liệu nguồn ứng viên này có đủ để lấp đầy vị trí trống mỗi lúc một nhiều trong thời kì mật độ nhảy việc cao như hiện nay?

Giảm bớt căng thẳng về mặt thời gian

Một trong những ưu điểm cực lớn mà các nhà tuyển dụng thường hay bỏ qua khi nhắc tới khi tuyển lập trình viên bị động là họ bớt thấy áp lực hơn trong tình huống phải ra quyết định tức thời.

  Vì sao lương khủng, đãi ngộ tốt vẫn khó tuyển IT?

TopDev sẽ giúp bạn rõ hơn với so sánh nhỏ sau. Với ứng viên chủ động tìm việc, có khả năng rất cao họ đang ứng tuyển cho nhiều công ty khác nhau. Nếu quá trình tuyển dụng của bạn không tinh gọn và mất nhiều thời gian, ứng viên đó đã có thể chấp nhận làm ở một công ty khác. Và cho dù bạn có tăng độ hấp dẫn cho offer ngay từ đầu, họ vẫn chờ xem những công ty khác sẽ offer cho họ những gì. Kết quả là bạn sẽ đứng ngay ranh giới giữa sắp để mất một nhân tài và tăng chi phí cho doanh nghiệp.

tuyển lập trình viên

Ứng viên IT bị động – ngược lại, thường sẽ không ứng tuyển cho nhiều công ty đơn giản vì họ đâu có chủ động tìm việc! Nếu quá trình tuyển lập trình viên của bạn khá dài và rườm rà, bạn cũng không phải lo lắng ứng viên sẽ được mời gọi offer hấp dẫn hơn.

Thẳng thắn, khách quan và công bằng

Do ứng viên IT bị động không tìm kiếm việc làm, có khi là họ đã có chỗ làm ổn thỏa, nên bạn không phải sợ việc bị ứng viên nói dối, phóng đại khả năng bản thân, làm mọi cách để được chấp nhận vào công ty. Chỉ đơn giản là bạn tiếp cận họ, nêu rõ những gì bạn cần, bạn cho họ, họ cân nhắc và chấp nhận ứng tuyển mà thôi. Vừa tiết kiệm thời gian cho cả hai, mà quyền lợi của 2 bên cũng dễ dàng thống nhất và đảm bảo hơn.

Ứng viên tiềm năng trong tương lai

Điều hiển nhiên là không phải ứng viên nào bạn tiếp cận cũng chấp nhận làm cho bạn ngay lúc đó. Bạn có thể không nhận được phản hồi nào từ cái email đầu tiên, nhưng đừng bỏ cuộc. Bây giờ họ không chấp nhận không có nghĩa là vài tháng sau họ vẫn thế.

Thay vì bỏ cuộc hoặc theo đuổi họ đến cùng (càng khiến họ thấy hoảng sợ hơn với doanh nghiệp của bạn) thì TopDev khuyên là bạn nên giữ liên lạc với họ với mật độ ổn định, 1 lần/tháng chẳng hạn, vừa duy trì được mối liên hệ về lâu dài, vừa có thể thuyết phục họ ứng tuyển trong tương lai.

  4 bí kíp đẩy mạnh tuyển dụng IT trên Facebook ít người biết

  Cập nhật xu hướng Employer Branding Event cho nhà tuyển dụng IT

Làm sao để thu hút & tuyển lập trình viên – ứng viên IT

Một cách cơ bản cũng như quan trọng nhất mà TopDev thường hay nhấn mạnh trong các bài blog của mình là bạn phải đẩy mạnh “Thương hiệu tuyển dụng”. TopDev sẽ gợi ý cho bạn 2 cách để thu hút, tuyển lập trình viên bị động bằng qua việc thúc đẩy Employer Branding nhé.

Cách 1: Thương hiệu tuyển dụng gián tiếp qua Digital Channels

1. Bài đăng trên các trang Blog: Trên hệ thống Tuyển dụng của TopDev, có đến 70% ứng viên cập nhật kiến thức qua Tech blog, điều đó chứng tỏ rằng bạn có thể gia tăng mức độ nhận diện cho doanh nghiệp mình bằng việc đăng tải các bài blog với kiến thức hữu dụng, thông tin cần thiết để ứng viên dễ dàng tiếp cận.

Bạn có thể tận dụng trang Blog của doanh nghiệp bạn với vài nội dung như:

– Kiến thức lập trình hữu dụng

– Case studies thực tế từ công ty

– Chia sẻ kỹ thuật chuyên sâu từ team dev cũng như về môi trường và văn hóa làm việc…

Bên dưới là một số dữ liệu mà TopDev đã tiếp cận các dev để để tìm hiểu sâu hơn về thị hiếu, xu hướng cập nhật thông tin IT và học ngôn ngữ lập trình mới. Bạn có thể tham khảo và cân nhắc áp dụng vào xây dựng thương hiệu tuyển dụng cho doanh nghiệp mình nhé:

Tuy nhiên, nếu việc đó mất nhiều thời gian hay chưa thành công như mong đợi thì đừng quên là TopDev có cung cấp các bài viết xây dựng thương hiệu qua Techtalk.vn và Blog Topdev.vn nhé. Techtalk là chuyên trang tin tức và thông tin công nghệ hàng đầu Việt Nam với 1.500.000 lượt truy cập mỗi tháng. Bên cạnh đăng bài qua Techtalk, TopDev còn chia sẻ lên các Fanpage công nghệ với cộng đồng IT dày đặc như như TopDev, Hội những Dev vui tính, Tech Talk, Lập Trình Viên Confession, Anh Lập Trình Viên … giúp việc xây dựng thương hiệu đơn giản hơn rất nhiều.

TopDev Ecosystem traffic

2. Banner Hiển thị: Hiển thị banner trên các website công nghệ lớn (như Techtalk, TopDev.vn). Như đã đề cập ở trên, Techtalk có gần 1.500.000 truy cập/tháng và đến 99% đối tượng là lập trình viên, đây là những người thường xuyên truy cập Techtalk để cập nhật thông tin, dĩ nhiên là khi banner của bạn được đặt ở những web có lượng traffic cao như thế, bạn đang dần cải thiện mức độ nhận diện và khơi gợi sự tò mò từ những ứng viên tiềm năng về doanh nghiệp bạn đó.

3. Email Marketing: Một cách vô cùng quen thuộc để tiếp cận ứng viên bị động là trực tiếp gửi email quảng bá về doanh nghiệp, những vị trí còn trống cũng như những điều thú vị về công ty. Tuy nhiên vấn đề là làm sao để có database ứng viên IT dồi dào và sáng tạo được nội dung cực kì thu hút? Cả 2 điều kiện cần trên là cực kì thiết yếu để một chiến dịch Email Marketing hiệu quả. Thiếu yếu tố đầu thì sẽ không ai có động lực mở email bạn cả, nếu không có yếu tố 2 thì bạn đã bỏ lỡ quá nhiều ứng viên bị động bên ngoài kia.

TopDev có thể giúp kế hoạch Email Marketing hiệu quả hơn với kho dữ liệu 300.000 ứng viên IT, tỉ lệ mở trung bình lên đến 20% và tỉ lệ chuyển đổi cực ấn tượng.

Cách 2: Thương hiệu tuyển dụng trực tiếp qua Event

4. Tech Event/Workshop

Không gì bàn cãi khi các event chuyên ngành là nơi hội tụ những ứng viên tiềm năng đến tham gia và tìm hiểu thêm về IT, tuyển lập trình viên, đây là cơ hội cực kì lớn để bạn đẩy mạnh thương hiệu tuyển dụng của mình. Có thể nói đây là cách tốt nhất để branding và tiếp cận trực tiếp với ứng viên ngay tại event.

Bạn có thể tổ chức event với nội dung như: chia sẻ những bài toán kĩ thuật khó nhằn và cách xử lý mà doanh nghiệp bạn đã áp dụng thành công; câu chuyện có thật từ những người đứng đầu công ty hay từ 1 anh dev tiêu biểu chẳng hạn,..bất kì nội dung hấp dẫn nào để thu hút các ứng viên IT tham gia. Tuy nhiên, việc xây dựng nội dung hấp dẫn không quyết định 100% sự thành công trong tuyển dụng của bạn, bạn và doanh nghiệp phải nỗ lực nhằm tạo cho ứng viên cảm giác gần gũi, thân thiện, nắm rõ hơn về công ty bạn cũng như những tiềm năng cơ hội phát triển mà bạn mang lại cho họ.

Nếu như việc tự tổ chức mất nhiều chi phí và thời gian, TopDev có thể là trợ thủ đắc lực cho doanh nghiệp của bạn từ khâu lên nội dung, truyền thông, logistics, vận hành sự kiện và tuyển lập trình viên. Với năng lực tổ chức nhiều sự kiện lớn trong năm và tần suất hơn 15 sự kiện mỗi tháng, doanh nghiệp cũng có thể tận dụng xuất hiện thương hiệu tuyển dụng của mình tại các kỳ sự kiện này, với nội dung phong phú với các chủ đề từ Mobile, Database tới hot trend như Machine Learning, AI,… Tìm hiểu thêm tại đây nhé!

5. Tham gia các sự kiện công nghệ lớn

Bên cạnh các Tech event/Workshop đề cập bên trên, TopDev sẽ gợi ý 1 vài event lớn thường niên để bạn cân nhắc tham gia nhé:

  • Forbes Vietnam’s Tech Summit: hội nghị về công nghệ với diễn giả là các nhà đầu tư mạo hiểm, doanh nhân công nghệ tầm cỡ thế giới cùng chia sẻ tầm nhìn, tư duy về xu hướng công nghệ, thúc đẩy doanh nghiệp khởi nghiệp và mở ra khả năng phát triển mới.
  • Techfest Vietnam:còn gọi “Ngày hội Khởi nghiệp đổi mới sáng tạo”được tổ chức vào ngày 4-6/12 năm nay. Mục tiêu là nhằm quy tụ hệ sinh thái khởi nghiệp sáng tạo, kết nối đầu tư trong nước và quốc tế cũng như đề xuất cơ chế chính sách phục vụ Khởi nghiệp.
  • Vietnam Mobile Day: tập trung vào lĩnh vực ứng dụng di động, hơn 100 chủ đề chuyên sâu cùng đối tượng đa dạng như developer, marketer và designer. Ngoài ra đây cũng là nơi để triển lãm các sản phẩm, tiếp cận ứng viên tiềm năng phục vụ cho việc tuyển lập trình viên hiệu quả.
  • Vietnam Web Summit: sự kiện IT lớn và qui mô nhất Việt Nam tập trung về Công nghệ với diễn giả gồm quản lí cấp cao và chuyên gia hàng đầu. Điều quan trọng hơn đây là cơ hội lớn không được bỏ lỡ khi bạn muốn thu hút ứng viên IT bị động bởi có gần 10.000 người tham gia và hơn 3 triệu online reach. Ngày hội tuyển lập trình viên được tổ chức vào ngày 6,13/12 lần lượt tại HCM và Hà Nội với dự kiến hơn 10.000 người tham gia.

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

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

TopDev tổng hợp

  TOP 20 thách thức tuyển dụng nhân sự IT năm 2024 (Phần 1)

  Cập nhật thông tin tuyển dụng IT - Lập trình viên tháng 7/2021