Home Blog Page 53

Phiên bản LTS là gì? Khi nào nên sử dụng phiên bản LTS

Phiên bản LTS là gì? Khi nào nên sử dụng phiên bản LTS

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

I. LTS là gì?

Trong thế giới công nghệ, thỉnh thoảng chúng ta thường bắt gặp cụm từ “LTS“. Ví dụ như Ubuntu 16.04 LTS, Ubuntu 18.04 LTS, Laravel 6 LTS,… Vậy LTS có nghĩa là gì?

LTS là viết tắt của Long Term Support có nghĩa là Hỗ trợ dài hạn.

Như định nghĩa trên:

các phiên bản có gắn mác LTS sẽ là phiên bản được hỗ trợ dài hạn. Tức là cho dù đã phát hành được một thời gian và kể cả đã có phiên bản khác mới hơn được phát hành thì phiên bản có gắn mác LTS sẽ vẫn được hỗ trợ bảo trì như bình thường.

Ví dụ một ứng dụng A phát hành phiên bản 4.0 LTS vào năm 2020, hỗ trợ bảo trì tới năm 2024. Thì trong khoảng thời gian từ năm 2020 tới năm 2024 có thể ứng dụng A đã phát hành thêm các phiên bản 5.0, 6.0 khác, nhưng phiên bản 4.0 vẫn sẽ được cập nhật các bản vá lỗi và vá lỗi bảo mật một như bình thường.

  Hướng dẫn tạo certificate SSL trên ubuntu (file key, pem)

II. Nên sử dụng phiên bản LTS khi nào?

Việc sử dụng phiên bản LTS sẽ đem lại một số lợi thế sau:

Phiên bản LTS thường là các phiên bản hoạt động ổn định, có cộng đồng sử dụng đông đảo.

Không tốn thời gian, chi phí cho việc phải thường xuyên cập nhật phiên bản mới mà vẫn nhận được sự hỗ trợ từ chính tổ chức phát hành.

Trên là hai lý do cơ bản nhất khiến bạn nên sử dụng phiên bản có gắn mác LTS thay vì các phiên bản thông thường khác. Tuy nhiên bạn vẫn nên sử dụng các phiên bản thông thường (hoặc phiên bản mới nhất) nếu như 2 lợi thế kể trên không đặc biệt quan trọng với bạn.

Tham khảo việc làm CSS hấp dẫn trên TopDev

Công ty mình đang làm hiện tại luôn ưu tiên sử dụng các phiên bản LTS thay vì các phiên bản khác (kể cả phiên bản mới nhất), vì sản phẩm của công ty luôn yêu cầu tính ổn định cao. Hơn nữa mọi người cũng muốn tập trung nguồn lực để phát triển các business của sản phẩm thay vì chỉ trực có phiên bản mới là update.

Còn với cá nhân mình, trong các dự án dạng “làm chơi cho vui” thì cứ phiên bản mới nhất là mình quất. Cốt lõi là muốn trải nghiệm các tính năng mới, bởi các phiên bản hỗ trợ dài hạn cũng thường đi với sự lỗi thời.

  Xử lý SSL Certificate trong Selenium WebDriver

III. Tổng kết

Tổng kết lại thì có một số luận điểm sau:

  • LTS là Long Term Support – Hỗ trợ dài hạn, ám chỉ phiên bản được hỗ trợ dài hạn cho dù đã có phiên bản khác mới hơn.
  • Phiên bản LTS có tính ổn định cao.
  • Phiên bản LTS nên được sử dụng trong các sản phẩm của cơ quan tổ chức cần tính ổn định cao.

Trên là một số quan điểm, kiến thức của mình về các phiên bản dạng LTS, hy vọng sẽ giúp ích được cho các bạn.

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

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

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

Thiết kế service có tải ghi cao không gây tranh chấp tài nguyên

Thiết kế service có tải ghi cao không gây tranh chấp tài nguyên

Để đảm bảo một hệ thống chạy tốt và ổn định, các việc thiết kế hệ thống như : chọn mô hình (micromonolithic), loại database, cách truyền tải dữ liệu (message queuehttpsocket,..), cách load balancing,… là việc rất quan trọng đánh dấu sự thành công của hệ thống. Song song với đó việc chúng ta thiết kế một service cũng là một mấu chốt quan trọng. Service bạn chịu trách nhiệm thiết kế có thể có các thao tác đọc ghi trên một dữ liệu tranh chấp. Khi 2 luồng của service của bạn cùng sửa một tài nguyên bị tranh chấp sẽ gây ra sự sai sót của hệ thống. Vậy khi thiết kế chúng ta cần có các kỹ thuật tránh điều này. Trong bài viết này tôi sẽ chia sẻ kinh nghiệm của mình khi thiết kế các service như vậy. Đây là phần một của bài viết sẽ nói về cách các bạn xử lý dữ liệu khi đến service chưa nói đến phân tải khi bạn có nhiều service cùng thực hiện một việc cũng như các service cùng một việc sẽ đồng bộ với nhau như thế nào.

Giả sử chúng ta cần thiết kế một service cho phép khách hàng thực hiện rút tiền. Chúng ta có một bảng đơn giản lưu lại thông tin của khách hàng như sau.

CREATE TABLE `users` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int DEFAULT NULL,
  `total_money` int DEFAULT NULL,
  `version` int DEFAULT '1',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6028 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

Tôi sẽ insert trước vài dữ liệu vào bảng này.

mysql> select * from users;
+----+--------+------+-------------+---------+
| id | name   | age  | total_money | version |
+----+--------+------+-------------+---------+
|  1 | demtv1 |    1 |           0 |       1 |
|  2 | demtv2 |    2 |          10 |       1 |
|  3 | demtv3 |    3 |          90 |       1 |
|  4 | demtv4 |    4 |          50 |       1 |
|  5 | demtv5 |    5 |          70 |       1 |
+----+--------+------+-------------+---------+

Yêu cầu của service là khi khách hàng rút tiền số dư sẽ được thay đổi và được lưu lại trong database. Trong đề bài này phần tài nguyên tranh chấp là số tiền của khách hàng. Chúng ta sẽ thiết kế theo mô hình đơn giản sau

simpleService.png

  Lưu ý cho Lock trong Java

  Hướng dẫn Java Design Pattern – State

Cách đơn giản để tránh tranh chấp các loại tài nguyên này là bạn chỉ cho phép một luồng được thực hiện với thao tác với tài nguyên tranh chấp. Trong java chúng ta có thể dùng synchronized hoặc lock.

      public synchronized User doUpdate(int amount){
        //...
        user.setTotalMoney(user.getTotalMoney() - withDrawRequest.getAmount());
        user = service.updateUser(user);
        CacheManager.user.put(user.getId(), user);
        response.setMsg("ok");

        //...
    }

    private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    private final ReentrantReadWriteLock.WriteLock lock = readWriteLock.writeLock();
    public  User doUpdate(int amount){
        lock.lock();
        try{
            //...
            user.setTotalMoney(user.getTotalMoney() - withDrawRequest.getAmount());
            user = service.updateUser(user);
            CacheManager.user.put(user.getId(), user);
            response.setMsg("ok");

            //...
        }finally {
            lock.unlock();
        }
    }
  • Dễ implement không cần database để xử lý tranh chấp
  • Không thể phục vụ nhiều khách hàng cùng lúc được.
  • Khó triển khai trên nhiều node service với các cách phân tải hay dùng hiện nay ví dụ : roundrobin, ip, WeightedResponseTimeRule … Phải có bộ phân tải hợp lý sao cho mỗi một node service chỉ phục vụ một số lượng user nhất định.

Tham khảo việc làm Java hấp dẫn trên TopDev

Với thiết kế này trên database sẽ có 1 trường mang đánh dấu là version của dữ liệu khi 2 luồng cùng thực hiện update trên cùng một dữ liệu trên database thì chỉ có 1 luồng thực hiện update thành công. Kỹ thuật đó là optimistic locking chi tiết mọi người xem tại link. Với spring boot các bạn có thể tham khảo tại link. Hoặc tham khảo đoạn code dưới đây

import lombok.Data;

import javax.persistence.*;

@Entity
@Table(name = "users")
@Data
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    private String name;

    private int age;

    private int totalMoney;

    @Version
    private int version;

}

// thao tác với database
   try {
      user = service.updateUser(user);
      CacheManager.user.put(user.getId(), user);
      response.setMsg("ok");
   } catch (IllegalStateException exception) {
      exception.printStackTrace();
      response.setMsg("version is not ok");
   }
  • Phương pháp này có thể phục vụ nhiều khách hàng khác nhau cùng thực hiện thao tác rút tiền.
  • Nếu bạn có nhiều node service phương pháp này vẫn phục vụ tốt cho bạn không sợ sai lệch dữ liệu
  • Rất dễ dàng để implement với tất cả developer
  • Phương pháp phải dùng database để bảo vệ tài nguyên tranh chấp gây lên cao tải cho database. Khi database cao tải bạn tăng số lượng service cũng không làm hệ thống bạn chạy tốt hơn.

Ý tưởng của request rất đơn giản thay vì mỗi request đến chúng ta có một luồng không xác định xử lý và thao tác với database. Giờ chúng ta sẽ tạo trước một số lượng luồng xử lý với database nhất định. Sau đó mỗi request đến ta sẽ lần lượt chia vào từng luồng này để xử lý. Điều này dẫn đến chúng ta sẽ ít sảy ra trường hợp insert fail vào database hơn vì với cùng request của một user chúng ta đã chỉ có 1 luồng duy nhất thao tác với nó nên trong cùng một node service sẽ không gây ra tranh chấp tài nguyên.

sharding_request.png

  • Không cần dùng đến database để xử lý tài nguyên tranh chấp cho nên không gây cao tải nên database khiến hệ thống chạy nhanh hơn. Khi bị hệ thống cao tải có thể add thêm service để phục vụ.
  • Nếu database bị cao tải ta có thể sử dụng phương pháp acsync insert/update vào database không gây ảnh hưởng đến trải nghiệm khách hàng.
  • Khó implement với những developer mới code. Mọi người có thể tham khảo link github sau được implement bằng springboot. Nếu nó có ích cho tôi xin 1 sao nhé. :))
  • Khi có nhiều node service thì cách này sẽ không thực sự hiệu quả với các cách load balacing thông thường như : roundrobin, ip, WeightedResponseTimeRule,… Vì như thế chúng ta sẽ không biết được cùng một user có rơi vào 2 node khác nhau không. Chúng ta nên sử dụng thêm version trong database.
  • Khi triển khai nhiều node service chúng ta cần có phương pháp phân tải thích hợp cho mỗi user sẽ chỉ vào một node nhất định. Khi node đó bị chết thì request của user đó sẽ chỉ chuyển sang một node khác. Có cơ hội sẽ trình bài ở các phần sau.

Ở đây tôi đã trình bày xong các cách giúp mọi người có thể thực hiện để tránh tranh chấp tài nguyên khi lập trình vào các request phải thay đổi dữ liệu hy vọng sẽ giúp ích được cho mọi người.

Tất cả các phương pháp đều có thể kết hợp với cache để tăng tốc độ khi không cần thực hiện giao tiếp nhiều với database. Ở các phần sau tôi sẽ giới thiệu một cách phân tải khá thông minh để áp dụng với cách thứ 3 trong bài này và nếu mọi người thấy việc implement cách thứ 3 khá khó thì tôi cũng sẽ có bài hướng dẫn mọi người implement tùy xem Hà Nội cách ly bao ngày nữa :))

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

Xem thêm:

Tuyển dụng IT lương cao, đãi ngộ hấp dẫn. Ứng tuyển ngay!

Đồng bộ dữ liệu giữa MongoDB với Elasticsearch bằng Transporter

Đồng bộ dữ liệu giữa MongoDB với Elasticsearch bằng Transporter

Bài viết được sự cho phép của tác giả Trần Hữu Cương

Trong bài này mình sẽ làm ví dụ chuyển data từ MongoDB sang Elasticsearch bằng Transport.

1. Transporter là gì? Cài đặt transporter trên ubuntu

Transporter là một phần mềm mã nguồn mở để di chuyển / đồng bộ dữ liệu trên các kho dữ liệu khác nhau.

Các kho dữ liệu được đồng bộ ở đây có thể là database, files…

Dữ liệu được đọc từ kho dữ liệu nguồn (source) sau đó được chỉnh sửa, tách lọc… (transformer) rồi chuyển tới kho dữ liệu đích (sink) thông qua pipeline do bạn định nghĩa.

  Truy vấn dữ liệu MongoDB

Cài đặt transport trên ubuntu

Download transporter:

wget https://github.com/compose/transporter/releases/download/v0.5.2/transporter-0.5.2-linux-amd64

(Download các phiên bản khác tại đây)

Chuyển các file vừa tải về vào folder /usr/local/bin/transporter hoặc folder nào đó bạn thích.

sudo mv transporter-*-linux-amd64 /usr/local/bin/transporter

Run transporter

chmod +x /usr/local/bin/transporter

Kiểm tra transport sau khi cài đặt bằng lệnh transporterĐồng bộ dữ liệu giữa MongoDB với Elasticsearch bằng Transporter

Tham khảo việc làm MongoDB hấp dẫn trên TopDev

2. Chuyển dữ liệu từ MongoDB sang Elasticsearch

(Xem lại: Hướng dẫn cài đặt MongoDB)

(Xem lại: Hướng dẫn cài đặt Elasticsearch)

Trong ví dụ này mình sẽ chuyển dữ liệu trong database demo sang elasticsearch.

B1: Tạo dữ liệu cho database demo:

db.player.insert({'name':'ronaldo','position':'striker'})
db.player.insert({'name':'buffon','position':'goalkeeper'})

tạo dữ liệu trên database mongo tạo dữ liệu trên database mongo

B2: Tạo pipeline để chuyển dữ liệu từ MongoDB sang Elasticsearch bằng lệnh:

transporter init mongodb elasticsearch

Tạo pipeline để chuyển dữ liệu từ MongoDB sang Elasticsearch

Kết quả là file pipeline.js được tạo ra, file này sẽ chứa các thông tin nguồn, đích của dữ liệu:

var source = mongodb({
  "uri": "${MONGODB_URI}"
  // "timeout": "30s",
  // "tail": false,
  // "ssl": false,
  // "cacerts": ["/path/to/cert.pem"],
  // "wc": 1,
  // "fsync": false,
  // "bulk": false,
  // "collection_filters": "{}",
  // "read_preference": "Primary"
})

var sink = elasticsearch({
  "uri": "${ELASTICSEARCH_URI}"
  // "timeout": "10s", // defaults to 30s
  // "aws_access_key": "ABCDEF", // used for signing requests to AWS Elasticsearch service
  // "aws_access_secret": "ABCDEF" // used for signing requests to AWS Elasticsearch service
  // "parent_id": "elastic_parent" // defaults to "elastic_parent" parent identifier for Elasticsearch
})

t.Source("source", source, "/.*/").Save("sink", sink, "/.*/")

Các bạn có thể tạo biến môi trường MONGODB_URI và ELASTICSEARCH_URI tương ứng hoặc có thể sửa trực tiếp vào file pipeline.js.

Ở đây mình tạo biến môi trường:

MONGODB_URI sẽ là uri tới database demo trên mongodb

export MONGODB_URI='mongodb://localhost/demo'

ELASTICSEARCH_URI sẽ là uri đích để chứa dữ liệu trên elasticsearch:

export ELASTICSEARCH_URI='http://localhost:9200/demo'
  MongoDB là gì? Cơ sở dữ liệu phi quan hệ

B3: chạy file pipeline.js để chuyển dữ liệu từ mongodb sang elasticsearch

transporter run pipeline.js

Kết quả:chạy file pipeline.js để chuyển dữ liệu từ mongodb sang elasticsearch

Kiểm tra lại dữ liệu trên elasticsearch bằng lệnh:

curl $ELASTICSEARCH_URI/_search?pretty=true

Kiểm tra lại dữ liệu trên elasticsearch bằng lệnh:

Đó, tất cả dữ liệu trên database demo đã được chuyển sang elasticsearch.

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

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

Xem thêm tuyển dụng nhân viên it hấp dẫn trên TopDev

Chat GPT là gì? Ứng dụng tuyệt vời và cách chatGPT hoạt động

Chat GPT là gì

ChatGPT là gì mà khiến anh em bà con không chỉ trong mà còn cả ngoài ngành phải thử ít nhất một lần? Điều gì khiến Chat GPT trở nên hot như vậy?

Trong thế giới công nghệ hiện nay, trí tuệ nhân tạo (AI) đang dần trở thành một phần không thể thiếu của cuộc sống. Một trong những công nghệ AI đang thu hút sự chú ý là ChatGPT. Vậy Chat GPT là gì? Nó có thể làm gì và ứng dụng như thế nào? Hãy cùng tìm hiểu trong bài viết này

Chat GPT là gì? Ứng dụng tuyệt vời và cách chatGPT hoạt động
Chat GPT là gì? Ứng dụng tuyệt vời và cách chatGPT hoạt động

Chat GPT là gì?

Chat GPT hay chatGPT, viết tắt của Chat Generative Pre-trained Transformer là một mô hình AI được phát triển bởi OpenAI. Nó sử dụng các thuật toán deep learning để hiểu và tạo ra văn bản tự nhiên giống như con người. Chat GPT có khả năng trả lời câu hỏi, viết văn bản, dịch ngôn ngữ, và thậm chí tham gia vào các cuộc trò chuyện phức tạp.

ChatGPT là mô hình được đào tạo để có thể tương tác theo cách đàm thoại. Ở định dạng đối thoại, Chat GPT có thể trả lời các câu hỏi tiếp theo (có tính kế tiếp), thừa nhận lỗi nếu nó có lỗi. Từ chối các yêu cầu không phù hợp. Chat GPT là mô hình anh em với InstructGPT, được đào tạo để làm theo hướng dẫn ngay lập tức và cung cấp phản hồi chi tiết.

OpenAI, một công ty nghiên cứu và phát triển về AI có trụ sở ở San Francisco đã ra mắt ChatGPT vào ngày 30 tháng 11 năm 2022. Bản chất của chatGPT vẫn đang là một mô hình sử dụng trí tuệ nhân tạo. Hằng ngày vẫn đang học hỏi chứ không phải là đã hoàn thành.

Chat GPT
ChatGPT là gì?

Chat GPT cho phép người dùng đặt câu hỏi hoặc kể lại một câu chuyện. Từ đó BOT sẽ trả lời bằng câu chuyện hoặc câu trả lời có liên quan. Giao diện được thiết kế cho gần giống nhất với cuộc trò chuyện giữa con người với con người.

Các phiên bản chatGPT hiện nay

Kể từ khi ra mắt, Chat GPT đã trải qua nhiều phiên bản nâng cấp để cải thiện hiệu suất và khả năng xử lý. Các phiên bản chính bao gồm:

GPT-1

  • Giới thiệu: GPT-1 là phiên bản đầu tiên của mô hình GPT được phát triển bởi OpenAI và ra mắt vào năm 2018. Đây là bước đầu tiên trong việc sử dụng kiến trúc Transformer để xử lý ngôn ngữ tự nhiên.
  • Cải tiến chính: GPT-1 sử dụng 117 triệu tham số, đánh dấu sự chuyển đổi từ các mô hình truyền thống sang kiến trúc Transformer, giúp cải thiện đáng kể hiệu suất xử lý ngôn ngữ.

GPT-2

  • Giới thiệu: Ra mắt vào năm 2019, GPT-2 là phiên bản cải tiến của GPT-1 với khả năng xử lý ngôn ngữ mạnh mẽ hơn.
  • Cải tiến chính: GPT-2 có 1,5 tỷ tham số, lớn hơn nhiều so với GPT-1, cho phép mô hình tạo ra văn bản tự nhiên hơn và phản hồi phức tạp hơn. GPT-2 có khả năng hoàn thành các nhiệm vụ như viết tiếp câu, trả lời câu hỏi, và thậm chí tạo ra đoạn văn từ một số gợi ý ban đầu.

GPT-3

  • Giới thiệu: GPT-3 được ra mắt vào năm 2020 và là phiên bản phổ biến nhất hiện nay của OpenAI.
  • Cải tiến chính: GPT-3 sử dụng tới 175 tỷ tham số, một bước nhảy vọt lớn so với GPT-2. Điều này giúp GPT-3 có khả năng hiểu và tạo ra văn bản với mức độ phức tạp và chính xác cao hơn nhiều. Nó có thể thực hiện nhiều tác vụ phức tạp như dịch ngôn ngữ, viết bài, sáng tác nhạc, và tham gia vào các cuộc trò chuyện dài và chi tiết.

GPT-4

    • Giới thiệu: GPT-4 là phiên bản mới nhất, ra mắt vào năm 2023.
    • Cải tiến chính: GPT-4 tiếp tục nâng cao khả năng xử lý ngôn ngữ và tích hợp nhiều cải tiến về hiệu suất và độ chính xác. Mặc dù OpenAI không tiết lộ chính xác số lượng tham số của GPT-4, nhưng nó được cho là lớn hơn và hiệu quả hơn GPT-3. GPT-4 có khả năng hiểu ngữ cảnh tốt hơn, giảm thiểu lỗi và cung cấp các phản hồi mượt mà và tự nhiên hơn.

Tìm hiểu thêm về các phiên bản GPT-4 phát hành mới nhất: GPT-4oGPT-4o mini

GPT-5

Chat GPT-5 dự kiến được ra mắt vào cuối năm 2025 hoặc đầu năm 2026 (theo Giám đốc công nghệ (CTO) của OpenAI – Mira Murati cho biết). Bà Mira tiết lộ rằng GPT-5 sẽ là thế hệ có thể đạt được trí thông minh của một tiến sĩ trong một số lĩnh vực nghiên cứu cụ thể. Để so sánh, GPT-3 tương đương với mức độ thông minh của một đứa trẻ, trong khi GPT-4 giống với mức độ thông minh của học sinh trung học.

Chat GPT hoạt động ra sao?

Chat GPT hoạt động ra sao?
Chat GPT hoạt động ra sao?

Chat GPT hoạt động dựa trên mô hình học máy tiên tiến gọi là Transformer, được huấn luyện trên lượng lớn dữ liệu văn bản để hiểu và tạo ra văn bản tự nhiên. Dưới đây là mô tả chi tiết về cách thức hoạt động của Chat GPT:

Kiến trúc Transformer

Kiến trúc Transformer là nền tảng của Chat GPT, được giới thiệu trong bài báo “Attention is All You Need” bởi Vaswani et al. vào năm 2017. Transformer sử dụng cơ chế Attention, cho phép mô hình tập trung vào các phần quan trọng của văn bản đầu vào trong quá trình xử lý.

Quá trình huấn luyện

Chat GPT được huấn luyện thông qua hai giai đoạn chính: tiền huấn luyện (pre-training) và tinh chỉnh (fine-tuning).

  1. Tiền huấn luyện (Pre-training)

Trong giai đoạn này, mô hình được huấn luyện trên một lượng lớn dữ liệu văn bản từ internet. Mục tiêu là giúp mô hình học cách dự đoán từ tiếp theo trong một câu. Cụ thể, GPT sử dụng phương pháp học máy không giám sát để huấn luyện trên các cặp câu liên tiếp, qua đó học được các cấu trúc ngữ pháp, ngữ nghĩa và thông tin ngữ cảnh từ dữ liệu đầu vào.

  1. Tinh chỉnh (Fine-tuning)

Sau khi hoàn thành giai đoạn tiền huấn luyện, mô hình được tinh chỉnh trên một tập dữ liệu nhỏ hơn, có giám sát, để cải thiện độ chính xác và khả năng đáp ứng cho các tác vụ cụ thể. Giai đoạn này sử dụng các dữ liệu đã được gán nhãn, bao gồm các câu hỏi và câu trả lời hoặc các đoạn văn bản có chủ đề nhất định. Điều này giúp mô hình hiểu rõ hơn về các yêu cầu cụ thể và cải thiện khả năng phản hồi chính xác.

Cơ chế Attention

Cơ chế Attention là một phần quan trọng của Transformer, cho phép mô hình tập trung vào các từ quan trọng trong câu để hiểu ngữ cảnh và mối quan hệ giữa các từ. Attention giúp mô hình xác định và tập trung vào các từ có liên quan trực tiếp đến từ đang được dự đoán, qua đó cải thiện độ chính xác của phản hồi.

Tạo văn bản

Khi nhận được đầu vào từ người dùng, Chat GPT sử dụng các kiến thức đã học trong quá trình huấn luyện để tạo ra văn bản đầu ra. Quá trình này bao gồm các bước sau:

  1. Tiếp nhận đầu vào: Chat GPT nhận một câu hỏi hoặc yêu cầu từ người dùng.
  2. Phân tích ngữ cảnh: Mô hình sử dụng các kiến thức đã học để phân tích ngữ cảnh và hiểu yêu cầu của người dùng.
  3. Tạo văn bản: Sử dụng cơ chế Attention và các tham số đã được huấn luyện, Chat GPT dự đoán từ tiếp theo và tạo ra câu trả lời phù hợp.
  4. Phản hồi: Mô hình gửi câu trả lời trở lại cho người dùng.

Tham khảo việc làm AI hấp dẫn trên TopDev!

Chúng ta có thể sử dụng Chat GPT như thế nào?

ChatGPT cũng có thể được sử dụng để tạo trải nghiệm kể chuyện tương tác, cho phép người dùng khám phá và học hỏi từ thế giới ảo.

Với Chat GPT, anh em có thể sử dụng vào các mục đích dưới đây:

  • Tạo phản hồi trong chatbot hoặc trợ lý ảo để cung cấp tương tác tự nhiên và hấp dẫn hơn với người dùng (kiểu con bot này nói chuyện như thật zậy chời).
  • Lên ý tưởng nội dung về từ khóa hoặc chủ đề (thời đại viết bài bằng AI tới đây rồi đấy thôi)
  • Tạo thông tin liên lạc được cá nhân hóa, chẳng hạn như phản hồi email hoặc đề xuất sản phẩm (hỏi phát biết ngay bố mày là ai)?

Ngoài ra, một số nghề có thể biến mất nếu Chat GPT hoạt động xuất sắc.

  • Tạo nội dung tiếp thị như bài đăng trên blog hoặc cập nhật trên mạng xã hội (nghề content writer có thể ra đi).
  • Dịch văn bản từ ngôn ngữ này sang ngôn ngữ khác (học nhiều học lâu có khi google dịch cũng ra đi luôn).
  • Tóm tắt tài liệu dài bằng cách cung cấp toàn văn và yêu cầu ChatGPT tạo bản tóm tắt ngắn hơn (rồi nhà báo ngày viết trăm bài lun)
  • Sử dụng câu trả lời do chatbot tạo ra để tạo công cụ chăm sóc khách hàng tự động (rồi mẹ chăm sóc khách hàng hoạt động năm 365 ngày lun)

Hạn chế của ChatGPT

Mặc dù Chat GPT có nhiều ưu điểm và ứng dụng hữu ích, nó cũng gặp phải một số hạn chế đáng kể. Dưới đây là các hạn chế chính của Chat GPT:

1. Thiếu hiểu biết ngữ cảnh sâu

Chat GPT, dù có khả năng xử lý và tạo ra văn bản tự nhiên, đôi khi vẫn gặp khó khăn trong việc hiểu ngữ cảnh phức tạp hoặc đa nghĩa. Nó có thể đưa ra các phản hồi không chính xác hoặc không phù hợp nếu ngữ cảnh không được xác định rõ ràng từ đầu.

2. Phụ thuộc vào dữ liệu huấn luyện

Chất lượng và độ chính xác của Chat GPT phụ thuộc rất nhiều vào dữ liệu huấn luyện. Nếu dữ liệu đầu vào có sai sót hoặc thiên lệch, kết quả đầu ra của mô hình cũng sẽ bị ảnh hưởng. Điều này có thể dẫn đến việc mô hình tạo ra thông tin không chính xác hoặc phản ánh các thiên lệch có trong dữ liệu.

3. Rủi ro bảo mật

Chat GPT có thể bị lợi dụng để tạo ra thông tin sai lệch, spam, hoặc thực hiện các hành vi lừa đảo. Khả năng tạo ra văn bản giống như con người khiến nó trở thành công cụ tiềm năng cho các hoạt động không lành mạnh nếu không được kiểm soát chặt chẽ.

4. Thiếu tính sáng tạo thực sự

Mặc dù Chat GPT có thể tạo ra văn bản mới từ dữ liệu đã học, nó vẫn dựa vào các mẫu và thông tin đã có trong dữ liệu huấn luyện. Điều này nghĩa là mô hình có thể thiếu tính sáng tạo thực sự và khó có thể đưa ra các ý tưởng hoàn toàn mới mẻ hoặc khác biệt.

5. Hiệu suất không ổn định

Hiệu suất của Chat GPT có thể không nhất quán trong các tình huống khác nhau. Đôi khi, mô hình có thể cung cấp các phản hồi xuất sắc, nhưng trong những trường hợp khác, nó lại có thể tạo ra các câu trả lời thiếu logic hoặc không liên quan.

6. Giới hạn về kiến thức cập nhật

Chat GPT không thể truy cập trực tiếp vào các sự kiện hoặc thông tin mới nhất sau khi quá trình huấn luyện kết thúc. Điều này có nghĩa là nó có thể không biết về các sự kiện hiện tại hoặc những thay đổi gần đây trong các lĩnh vực khác nhau.

7. Khả năng xử lý đa ngôn ngữ hạn chế

Mặc dù Chat GPT có thể xử lý nhiều ngôn ngữ, khả năng hiểu và tạo văn bản có thể không đồng đều giữa các ngôn ngữ khác nhau. Ngôn ngữ nào có ít dữ liệu huấn luyện hơn sẽ dẫn đến hiệu suất thấp hơn trong việc tạo ra các phản hồi chất lượng.

9. Thiếu khả năng tương tác đa phương thức

Hiện tại, Chat GPT chủ yếu xử lý văn bản. Nó không thể dễ dàng tương tác hoặc hiểu các dạng dữ liệu khác như hình ảnh, âm thanh, hoặc video, hạn chế khả năng ứng dụng trong các tình huống yêu cầu tương tác đa phương thức.

10. Phản hồi quá mức (Overfitting)

Trong một số trường hợp, Chat GPT có thể phản hồi quá mức, tạo ra văn bản dài hơn hoặc phức tạp hơn mức cần thiết. Điều này có thể dẫn đến sự mất mạch lạc và gây khó khăn cho người dùng trong việc hiểu rõ ý nghĩa của phản hồi.

Chat GPT là một công cụ mạnh mẽ nhưng cũng có những hạn chế cần được cân nhắc khi sử dụng. Việc nhận thức và hiểu rõ những hạn chế này sẽ giúp người dùng áp dụng Chat GPT một cách hiệu quả và tránh các rủi ro tiềm ẩn.

Chat GPT có khả dụng ở Việt Nam không?

Ứng dụng chat GPT đã có mặt ở Việt Nam
Ứng dụng chat GPT đã có mặt ở Việt Nam

Ngày đầu ra mắt, chatGPT chỉ truy cập và đăng kí tài khoản sử dụng ở một số quốc gia, và Việt Nam không nằm trong danh sách đó, nếu muốn sử dụng chúng ta phải mua tài khoản được đăng kí ở quốc gia khác.

Tuy nhiên vào ngày 02/11/2023, chat GPT đã chính thức có mặt ở Việt Nam, bạn có thể đăng ký và sử dụng miễn phí ChatGPT tại Việt Nam trên nền tảng website chat.openai.com, ứng dụng ChatGPT trên Android, iOS.

Chat GPT vs Google – nên dùng cái nào?

Chat GPT và Google là hai công cụ mạnh mẽ được sử dụng rộng rãi trên toàn thế giới. Tuy nhiên, mỗi công cụ có những ưu điểm và hạn chế riêng biệt, phục vụ cho các mục đích khác nhau. Dưới đây là sự so sánh chi tiết giữa Chat GPT và Google để giúp bạn quyết định nên sử dụng công cụ nào trong từng tình huống cụ thể.

  Chat GPT Google

Mục đích sử dụng

  • Tạo văn bản tự nhiên: Chat GPT được thiết kế để tạo ra văn bản tự nhiên giống như con người. Nó có thể tham gia vào các cuộc trò chuyện, trả lời câu hỏi, viết bài, sáng tác và dịch ngôn ngữ.
  • Hỗ trợ khách hàng: Chat GPT có thể được tích hợp vào các hệ thống hỗ trợ khách hàng để trả lời câu hỏi và giải quyết các vấn đề của người dùng.
  • Giáo dục và học tập: Chat GPT có thể cung cấp thông tin học thuật, giải đáp thắc mắc và giúp học sinh, sinh viên trong việc học tập.
  • Tìm kiếm thông tin: Google là công cụ tìm kiếm thông tin mạnh mẽ nhất thế giới, giúp người dùng tìm kiếm thông tin trên internet một cách nhanh chóng và hiệu quả.
  • Dịch vụ trực tuyến: Google cung cấp nhiều dịch vụ trực tuyến khác nhau như Gmail, Google Docs, Google Drive, Google Maps và YouTube.
  • Quảng cáo và kinh doanh: Google Ads và Google Analytics là công cụ quan trọng giúp doanh nghiệp quảng cáo sản phẩm và phân tích dữ liệu khách hàng.
Cách thức hoạt động
  • Xử lý ngôn ngữ tự nhiên (NLP): Sử dụng mô hình học máy và kiến trúc Transformer để hiểu và tạo ra văn bản tự nhiên dựa trên ngữ cảnh của câu hỏi hoặc yêu cầu.
  • Tương tác theo ngữ cảnh: Có khả năng duy trì ngữ cảnh trong cuộc trò chuyện, giúp phản hồi một cách mạch lạc và logic.
  • Thu thập và lập chỉ mục dữ liệu: Sử dụng các thuật toán tìm kiếm để thu thập, lập chỉ mục và xếp hạng hàng tỷ trang web trên internet.
  • Cung cấp kết quả tìm kiếm: Trả về danh sách các liên kết web liên quan đến từ khóa mà người dùng tìm kiếm, thường kèm theo các đoạn trích dẫn và thông tin bổ sung.
Ưu điểm
  • Tương tác tự nhiên: Có khả năng tạo ra văn bản tự nhiên và tham gia vào các cuộc trò chuyện phức tạp.
  • Linh hoạt: Ứng dụng trong nhiều lĩnh vực khác nhau từ hỗ trợ khách hàng đến sáng tác nghệ thuật.
  • Không yêu cầu từ khóa chính xác: Có thể hiểu và phản hồi dựa trên ngữ cảnh mà không cần từ khóa chính xác.
  • Tìm kiếm thông tin nhanh chóng: Có thể tìm kiếm thông tin từ hàng tỷ trang web chỉ trong vài giây.
  • Kiến thức cập nhật: Kết quả tìm kiếm thường xuyên được cập nhật, đảm bảo người dùng nhận được thông tin mới nhất.
  • Nhiều dịch vụ hỗ trợ: Cung cấp nhiều dịch vụ trực tuyến hữu ích cho cả cá nhân và doanh nghiệp.
Hạn chế
  • Thiếu kiến thức cập nhật: Kiến thức bị giới hạn trong phạm vi dữ liệu huấn luyện và không thể cập nhật theo thời gian thực.
  • Chi phí sử dụng cao: Việc sử dụng mô hình lớn như GPT-3 hoặc GPT-4 có thể tốn kém, đặc biệt khi sử dụng API
  • Phụ thuộc vào từ khóa: Cần sử dụng từ khóa chính xác để nhận được kết quả tìm kiếm phù hợp.
  • Không tương tác theo ngữ cảnh: Không thể duy trì ngữ cảnh cuộc trò chuyện và cung cấp phản hồi như con người.

 

Cập nhật và chỉnh sửa từ bài viết của tác giả: Kiên Nguyễn

Xem thêm:

Tìm kiếm việc làm IT mới nhất tại TopDev!

 

Hướng dẫn kết nối PHP với SQL Server

kết nối php với sql server

Kết nối hệ cơ sở dữ liệu với hệ thống backend là điều bắt buộc phải làm trước khi viết API hoặc thực hiện một số thao tác liên quan tới hệ cơ sở dữ liệu, bài viết này mình sẽ đi từng bước giúp anh em kết nối PHP với SQL Server ở local.

1. Cài đặt SQL Server

Kết nối php với SQL server sẽ đi qua 2 bước, anh em cứ từ từ nha. Không có gì nóng vội, ta cứ cài đặt đã. Đầu tiên, anh em truy cập trang web của microsoft về SQL Server tại link này. Kéo xuống bên dưới chỗ phía cho developer.

Sau khi đã tải về file exe để cài đặt, anh em double click lên. Mở ra trình cài đặt của SQL server

  Thói quen viết code an toàn trong khi xây dựng ứng dụng PHP

Ở bước lựa chọn có 3 lựa chọn cho anh em cài đặt SQL Server

  • 1. Basic: cài một phát xong luôn với tất cả thiết lập đều là thiết lập mặc định (khuyên dùng nếu không có gì đặc biệt)
  • 2. Custom: Cho phép custom một số thiết lập default ban đầu
  • 3. Download media: Tải về trước và cài đặt sau, tiết kiệm thời gian sau không cần phải tải nữa.

Không có gì thì anh em cứ chọn basic rồi next. Tới trình cài đặt.

Có thời gian thì đọc thêm license terms rồi next nha.

kết nối php với sql server

1 là đường dẫn mặc định cài SQL server, ấn vào 2 browser nếu anh em muốn thiết lập đường dẫn khác.

Xem thêm tuyển dụng PHP lương cao trên TopDev

2. Mở extension kết nối Php với SQL server

Để mở kết nối Php với SQL server, anh em cần chỉnh sửa file php.ini. File này mặc định sẽ comment một số extension kết nối tới hệ cơ sở dữ liệu

Anh em cài bản php nào sẽ mở kết nối tới bản php đó theo như đường dẫn dưới đây

kết nối php với sql server

Nếu anh em dùng Php XAMPP thì có thể đi thẳng tới php.ini thông qua lựa chọn dưới đây.

kết nối php với sql server

Sau khi đã đi tới thư mục có php.ini, anh em mở file lên và tìm tới dòng (trên windows)

extension=php_sqlsrv_72_ts.dll

Trên linux thì anh em tìm tới dòng này

extension=php_sqlsrv_72_nts.so

Sau khi đã mở comment các dòng này. Anh em tìm tới pdo, để PDO_SQLSRV có thể hoạt động, ta cần mở thêm pdo. Mở thêm comment của dòng này.

extension=php_pdo.dll

Trên linux

extension=pdo_sqlsrv.so

  Mẹo tối ưu câu lệnh truy vấn (query) SQL

3. Code PHP kết nối với SQL server.

Sau khi đã mở extension php.ini, anh em lưu lại, nếu cần có thể start lại XAMPP. Lúc này anh em đã sẵn sàng để kết nối PHP với SQL server.

Trước khi làm gì với Database đều cần phải mở kết nối. Đoạn code dưới đây giúp mở kết nối từ Php

 function OpenConnection()
    {
        $serverName = "tcp:myserver.database.windows.net,1433";
        $connectionOptions = array("Database"=>"AdventureWorks",
            "Uid"=>"MyUser", "PWD"=>"MyPassword");
        $conn = sqlsrv_connect($serverName, $connectionOptions);
        if($conn == false)
            die(FormatErrors(sqlsrv_errors()));

        return $conn;
    }

Phần serverName nếu anh em sử dụng local thì nó là localhost. Phần connectionOptions là các thông tin liên quan tới DB, Uid (tài khoản) và mật khẩu. Anh em chú ý là lưu ở array.

Sau khi đã mở kết nối tới database, anh em có thể thực hiện các câu truy vấn.

   function ReadData()
    {
        try
        {
            $conn = OpenConnection();
            $tsql = "SELECT [CompanyName] FROM SalesLT.Customer";
            $getProducts = sqlsrv_query($conn, $tsql);
            if ($getProducts == FALSE)
                die(FormatErrors(sqlsrv_errors()));
            $productCount = 0;
            while($row = sqlsrv_fetch_array($getProducts, SQLSRV_FETCH_ASSOC))
            {
                echo($row['CompanyName']);
                echo("<br/>");
                $productCount++;
            }
            sqlsrv_free_stmt($getProducts);
            sqlsrv_close($conn);
        }
        catch(Exception $e)
        {
            echo("Error!");
        }
    }

Câu truy vấn này thực hiện lấy companyName từ bảng Customer.

4. Tham khảo

Cảm ơn anh em đã đón đọc – Mong sẽ bổ ích cho anh em – Happy coding!

Tác giả: Kiên Nguyễn

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

Truy cập ngay việc làm IT đãi ngộ tốt trên TopDev

Các vai trò trong một team phát triển phần mềm

vai trò team phát triển phần mềm

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

Chào các bạn,

Có phải để tạo ra một sản phẩm phần mềm thì chỉ cần các bạn developer thôi là đủ không? Câu trả lời là vừa có … vừa không. Vì một team bao gồm những ai thì phụ thuộc rất nhiều vào quy mô, cũng như tốc tốc độ phát triển của dự án đó.

Để các bạn hiểu rõ về các vai trò trong một team phát triển sản phẩm, thì mình sẽ mô tả quá trình thay đổi của một team dự án, từ lúc nó bé xíu, cho tới lúc đã có tương đối đủ thành viên, như vậy bạn sẽ dễ hiểu hơn về vai trò của từng thành viên trong team.

Lưu ý: 
Không phải tất cả các dự án phần mềm đều có sự phát triển giống như trong bài viết này. Mình chỉ lấy ví dụ để các bạn dễ hình dung ra vai trò của từng bộ phận trong team hơn thôi nhé.

Vai trò của Developer

Developer là dân kỹ thuật chính hiệu, kỹ năng mạnh nhất của họ chính là viết code để tạo ra phần mềm.

Thời điểm này, dự án chỉ bao gồm 3 developer. Họ có chung ý tưởng, và quyết định hợp tác với nhau để cùng biến ý tưởng đó thành một sản phẩm thực tế. Họ phác thảo ý tưởng ra giấy, rồi phân chia công việc. Họ cũng bầu ra một leader (gọi là developer leader) để chịu trách nhiệm điều phối, và đảm bảo chất lượng sản phẩm.

Giai đoạn này, công việc chủ yếu là code, đôi khi phát sinh một số công việc khác nhưng không nhiều, cũng không quá khó, họ vẫn có thể tự chia nhau hoàn thành.

Sau một thời gian phát triển, họ đã có phiên bản đầu tiên, sẵn sàng ra mắt khách hàng, và hy vọng là sẽ có nhiều khách hàng sử dụng.

  Tech Lead là gì? Nhiệm vụ, vai trò của Tech Lead trong team

Vai trò của Product Owner (PO)

Sau khi ra mắt sản phẩm, cũng có một vài bug, nhưng nó không nghiêm trọng lắm, các developer vẫn làm việc bình thường, và sản phẩm cũng đã “nhen nhúm” có khách hàng sử dụng. Tuy nhiên, ý tưởng ban đầu của họ đã được khai thác hết, tất cả các tính năng cần thiết đều đã xuất hiện trên sản phẩm, họ bắt đầu cạn ý tưởng và không biết phải làm gì tiếp theo.

Các developer cũng bắt đầu ý thức được rằng, việc đưa ra một ý tưởng thì không khó, nhưng đưa ra một ý tưởng thiết thực thì lại rất khó. Trong khi họ là các developer, nên việc tìm ra một ý tưởng như vậy không phải là điều dễ dàng.

Họ bắt đầu đi tìm kiếm một product owner – người sẽ chịu trách nhiệm tìm ra các ý tưởng, sao cho các ý tưởng đó là hay, là thiết thực, vừa đem lại giá trị cho khách hàng, lại vừa đem lại lợi ích cho sản phẩm (gọi chung là tối ưu hóa sản phẩm).

Có Product Owner, các ý tưởng hay liên tục được đưa ra, nhờ đó mà sản phẩm phát triển nhanh hơn rất nhiều so với trước kia – cả về mặt tính năng lẫn số lượng khách hàng sử dụng.

Tham khảo Job FrontEnd HOT trên TopDev!

Vai trò của Business Analyst (BA)

Ban đầu, PO và các developer phối hợp với nhau rất tốt, công việc rất trôi chảy, suôn sẻ. Nhưng càng về sau, thì càng xuất hiện nhiều vấn đề, chủ yếu xoay quanh:

  • Sản phẩm đã trở nên khá phức tạp, và không một ai trong team có thể nhớ rõ chính xác nó hoạt động như thế nào. Nên các ý tưởng của PO khi đưa ra tuy rất phù hợp về mặt hướng đi, nhưng lại xung đột nhiều với các tính năng đã có.
  • Các ý tưởng mà PO đưa ra ngày càng phức tạp, và các developers sẽ không thể “nghe một lần rồi hiểu ngay”, nên họ thường xuyên code “lệch” so với ý tưởng của PO.
  • Các developer trễ deadline, do việc việc triển khai ý tưởng mới phải gánh thêm việc giải quyết xung đột với tính năng cũ, trong khi đó, không ai biết chính việc sửa tính năng cũ tốn bao nhiêu thời gian, có thể rất nhiều, hoặc rất ít.

Vì vậy, cả team quyết định sẽ phân tích kỹ lưỡng, đồng thời mô tả sử thay đổi của sản phẩm ra văn bản, coi nó là tài liệu mô tả yêu cầu trước khi code. Tuy nhiên, không biết nên để công việc này cho ai vì:

  • Vai trò của PO là người đi tìm các ý tưởng, và chứng minh là đó là ý tưởng thiết thực mà sản phẩm nên có. Đây là công việc cực kỳ quan trọng, PO không nên tốn thời gian vào việc mô tả chi tiết yêu cầu.
  • Nếu PO không làm công việc trên, thì developer lại càng không. Vì trò của developer chủ yếu là về mặt công nghệ – đây cũng là một công việc rất quan trọng, không nên để developer tốn thời gian vào việc viết mô tả chi tiết yêu cầu. Mặt khác, chính các developer sẽ là người chuyển yêu cầu thành code, nếu để họ để họ viết yêu cầu, thì không khác gì bảo họ viết hai lần, một lần bằng ngôn ngữ tự nhiên, và một lần viết bằng code.

Vì thế, team quyết định tìm thêm một bạn làm về business analyst (BA) – Chuyên viên phân tích nghiệp vụ.

BA sẽ đảm nhiệm phân tích ý tưởng ban đầu của PO thành các yêu cầu cụ thể trên sản phẩm (như sản phẩm cần thêm, sửa, xóa tính năng gì), đồng thời văn bản hóa các yêu cầu đó thành tài liệu SRS (*), trực tiếp giải thích cho các developer hiểu. Nếu yêu cầu tính năng quá khó để miêu tả bằng văn bản, thì BA sẽ vẽ các bản mockup (*)prototype (*) để dễ hình dung hơn.

  Team Leader là gì? Những kỹ năng nào mà một Team Leader cần có?

Vai trò của UI/UX Designer

Kể từ khi có BA, công việc lại trở nên ổn định, deadline đã chính xác hơn trước, PO cũng tự tin đưa khi đưa ý tưởng mới mà không lo các developer than “Ui nó ảnh hưởng nhiều lắm, code phức tạp lắm“. Số lượng tính năng mới, và khách hàng vẫn liên tục tăng lên.

Về mặt team phát triển, cơ bản là không có vấn đề gì, nhưng vấn đề lúc này lại đến từ khía khách hàng. Ngoại trừ việc sản phẩm có một vài lỗi nhỏ, thì còn một vấn đề lớn nữa đó là “các tính năng quá khó để sử dụng”. Khách hàng đã tiếp cận với sản phẩm, nhưng rồi lại lặng lẽ đi ra vì … không biết dùng như thế nào.

Cả team từng cho rằng BA sẽ cần phân tích thêm cả việc sản phẩm nên thể hiện như thế nào với khách hàng, nhưng không, BA đang rất bận rộn với việc phân tích yêu cầu của PO. Mặt khác, BA sẽ tập trung trả lời cho câu hỏi “sản phẩm sẽ cần thay đổi những gì về mặt tính năng?“, chứ ít khi trả lời câu hỏi “sản phẩm phải làm thế nào để đẹp hơn và dễ dùng hơn“.

Vì thế, để sản phẩm thu hút hơn, và đem lại trải nghiệm tốt hơn với khách hàng, team đã tìm thêm một bạn UI/UX designer. Bạn này sẽ đảm nhiệm việc thiết kế giao diện (màu sắc, bố cục), và các luồng sử dụng trên sản phẩm, sao cho thân thiết, đẹp mắt, dễ tiếp cận và dễ dàng sử dụng với khách hàng, ngay cả khi họ là người mới.

Sau khi có UI/UX designer, sản phẩm như được lột xác. Bố cục rõ ràng, màu sắc hài hòa, cùng với một tính năng, trước kia khách hàng phải tốn 10 click, thì giờ chỉ tốn 3 click. Tóm lại trải nghiệm được tăng lên đáng kể.

Vai trò của Tester

Số lượng khách hàng sử dụng bây giờ đã rất nhiều, và các bug ngày trước được coi là nhỏ, thì bây giờ sẽ được coi là lớn, các bug ngày trước được coi là lớn, thì bây giờ không được phép xuất hiện trên sản phẩm.

Mặc dù các developer không cố tình tạo ra bug, họ cũng đã kiểm tra lại kỹ càng các tính năng trước khi đưa cho khách hàng sử dụng. Nhưng suy cho cùng, họ vẫn là con người, không thể tránh được thiếu sót, và các bug “không thể chấp nhận được” vẫn đôi lúc xuất hiện.

Vì vậy, team quyết định tìm thêm một bạn tester – người sẽ đảm bảo chất lượng sản phẩm trước khi nó tới tay khách hàng.

Từ khi có tester, các đợt cập nhật phiên bản mới đều được kiểm tra kỹ càng rồi mới đưa đến tay khách hàng, các bug “không thể chấp nhận được” đã không còn xuất hiện nữa.

Vai trò của team Manager

Điểm lại một chút, lúc này team đã có khá nhiều vai trò: developer, PO, UI/UX designer, tester. Và các bộ phận này này đang gặp một số vấn đề như sau:

  • Không biết cách phối hợp với nhau thế nào cho hiệu quả.
  • Lúc thì bộ phận này bận SML, còn bộ phận kia thì rảnh và ngược lại.
  • Đôi khi có các công việc “không tên”, thì không ai muốn nhận nó về mình, ai có lý do từ chối hợp lý.

Hiện tại thì team vẫn đang có một leader (chính là bạn developer được bầu ra ở level 1). Nhưng suy cho cùng đó là kiêm nhiệm vị trí, và bạn đó vẫn đang làm việc ở vị trí developer nhiều hơn.

Để team hoạt động hiệu quả hơn, team quyết định để bạn developer leader kia lên làm team manager – bạn này chịu trách nhiệm điều phối công việc trong team, cân bằng khối lượng công việc giữa các bộ phận, tìm ra quy trình phù hợp và áp dụng vào team.

Trong thực tế, nếu team không bầu được ai, thì có thể tuyển người mới. Tuy nhiên vị trí này ít khi được tuyển mới mà thường được cất nhắc từ người trong team hiện tại – nhất là với các team nhỏ.

Kể từ khi có team manager, công việc lại trôi chảy hơn nhiều, mọi người đi làm cảm thấy vui vẻ, không còn lo quá nhiều hoặc quá ít việc. Các bộ phận cũng phối hợp hiệu quả hơn do có quy trình làm việc rõ ràng.

Tạm kết câu chuyện của team tới đây, vì nếu mình viết tiếp thì sẽ rất dài, thậm chí không có hồi kết. Cũng như mình chia sẻ ở đầu bài viết, quy mô của dự án sẽ quyết định các vai trò trong team, tuy nhiên, đều tuân theo một quy luật là “nghẽn ở đâu, thì giãn nở ở đó”. Khi dự án phát triển tới mức độ được coi là lớn, thì bất kỳ một công việc nhỏ nào trước kia đều có thể trở nên cực kỳ phức tạp, và cần một bộ phận chuyên trách để xử lý – đó là lúc team cần bổ sung thêm một vai trò mới.

Ngoài các vai trò đã được nếu phía trên, thì dưới đây mình bổ sung thêm một số vai trò điển hình khác:

  • Vai trò của DevOps Developer: Chịu trách nhiệm về hạ tầng sản phẩm (server, mạng,…), giúp sản phẩm chạy ổn định với khách hàng.
  • Vai trò của Security: Đảm bảo hệ thống an toàn, không bị xâm nhập trái phép.
  • Vai trò của Software Architecture: Thiết kế kiến trúc của phần mềm, để sản phẩm có tính mở rộng cao, dễ dàng thay đổi, và ít để lại nợ công nghệ
  • SRS: Viết tắt của Software Requirement Specification, được dịch ra tiếng việt là Tài liệu đặc tả yêu cầu. SRS là tài liệu được sử dụng để mô tả chi tiết các yêu cầu chức năng và phi chức năng của hệ thống.
  • Prototype, mockup: Ám chỉ các bản vẽ mô tả về sản phẩm.

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

Những bài viết liên quan:

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

Top 7 câu hỏi phỏng vấn Backend Developer

phỏng vấn backend developer

Backend Developer chưa bao giờ hết hot là vị trí được tuyển dụng nhiều và trả lương cao chót vót, phỏng vấn Backend Developer cũng không hề dễ. Nói thì không phải troll chứ Frontend Developer luôn tạo ra những thứ hoa mỹ bóng bẩy. Ngược lại, Backend Developer luôn gồng gánh phần nặng nhất, chịu trách nhiệm cho hệ thống hoạt động ổn định.

Mà làm source code đẹp hay không ai biết, chỉ toàn meme chế backend là một đống hỗ độn, che dấu đằng sau cái vẻ đẹp lồng lộn của Frontend.

backend

Quả không điêu khi Backend Developer đòi hỏi một lượng kiến thức khổng lồ khi tham gia phỏng vấn. Mà có phải là code không đẹp đâu. Tí nữa rồi anh em sẽ rõ thông qua 1,2 câu hỏi về clean architecture. Code đẹp, structure đẹp cho bọn meme nó bớt chế.

Kiến thức cần có ở Backend Developer trải dài từ hệ cơ sở dữ liệu qua tới kinh nghiệm làm việc với API. Ở mức độ cao hơn, Backend Developer có kinh nghiệm còn cần có giải pháp cho những vấn đề hóc búa xảy ra trong quá trình làm việc.

Những kinh nghiệm này là kinh nghiệm thực tế, tức là trong quá trình làm việc xảy ra những vấn đề hóc búa ở phía Backend, tìm tòi xử lý các vấn đề. Tích luỹ thành kinh nghiệm.

  Lập trình Backend là gì? Backend Developer cần các kỹ năng nào?
  Mô tả công việc - Vị trí lập trình Backend

1. CAP Theorem là gì?

Bắt đầu danh sách câu hỏi phỏng vấn Backend Developer bằng một câu hỏi lý thuyết. Bắt đầu bằng câu hỏi này bởi vì đi thẳng vào từng ngôn ngữ lập trình thì sẽ có series phỏng vấn Java, Python sau cho anh em thoải mái focus vào từng ngôn ngữ.

Quay lại với câu hỏi đầu tiên, CAP Theorem là định lý ban đầu được tạo ra cho hệ thống phân tán (distributed computer system) bởi Eric Brewer. C,A,P là viết tắt của 3 yếu tố cần có. Kiến thức này khá là quan trọng với Backend Developer, người thường xuyên làm việc với hệ thống phân tán.

Bắt đầu với C – Consistency (tính nhất quán). Tính nhất quán ở đây mang ý nghĩ client luôn thấy cùng một data. Bất kể client đang được liên kết tới node nào. Để được vậy, phải thực hiện đồng bộ dữ liệu cho tất cả. Lặp lại cho tất cả các nốt.

Thứ hai là A – Availability – tính sẵn sàng. Tính sẵn sàng được hiểu rằng bất cứ khi nào client gửi request. Họ đều sẽ nhận được response. Thậm chí một hoặc vài node bị down.

Thứ ba là P (Partition tolerance). Phía bên hệ thống phân tán, lúc thiết kế phải đảm bảo sao cho khi một số node die, cả hệ thống vẫn hoạt động bình thường.

Nhiều tin tuyển dụng Backend lương cao trên TopDev

Phỏng vấn backend developer

Về câu hỏi này anh em có thể tham khảo qua bài viết này. Đây là câu hỏi lý thuyết cơ bản cho anh em học vừa mới ra trường hoặc đã nhiều năm kinh nghiệm đều cần phải nắm vững. CAP theorem tuy đơn giản nhưng là tiêu chuẩn cho tất cả các hệ thống lớn ở Amazon, Google. Anh em chú ý.

2. Tại sao bạn lại chọn kiến trúc micro services?

Câu hỏi thứ hai khi phỏng vấn Backend Developer là kiến trúc phổ biến đối với các hệ thống Microservices. Nhưng tại sao và lúc nào ta nên lựa chọn microservices?

Trả lời cho câu hỏi này, trước tiên là kiến trúc micro services có rất nhiều ưu điểm. Một số câu trả lời cho anh em có thể tham khảo

  • Microservices can adapt easily to other frameworks or technologies. – Microservices có thể dễ dàng thích ứng với các framework hoặc công nghệ khác.
  • Failure of a single process does not affect the entire system. – Việc một microservices bị fail có thể không ảnh hưởng tới toàn bộ hệ thống.
  • Provides support to big enterprises as well as small teams. – Microservices phù hợp cho cả doanh nghiệp lớn và các đội nhóm nhỏ hơn.
  • Can be deployed independently and in relatively less time – Có thể triển khai độc lập trong một thời gian ngắn hơn các kiến trúc thông thường.

Lý thuyết là vậy nhưng trong quá trình phỏng vấn, anh em có thể nêu thêm các ví dụ để làm rõ ý của mình. Ví dụ như deploy độc lập dùng docker hay kubenetes?. Trường hợp một microservices down tại sao lại không ảnh hưởng tới các services khác?.

3. SQL Injection là gì?

Câu hỏi này tập trung chủ yếu vào Web Security. Làm backend mà không biết hoặc không chú trọng tới security thì nguy hiểm lắm. Khái niệm và những lỗ hổng đã được phát hiện trước đây nếu anh em biết thêm thì quá tuyệt.

Chính vì vậy, câu hỏi thứ 3 trong bộ câu hỏi phỏng vấn backend developer là câu hỏi liên quan tới một lỗ hổng đã phát hiện từ lâu SQL Injection.

SQL Injection

Trả lời cho câu hỏi này anh em cần biết bản chất của Injection (chèn vào, tiêm chích vào). Bản chất phương thức tấn công này nhắm vào việc chèn các đoạn mã SQL không được phép. Thực hiện các câu SQL độc hại thông qua lỗ hổng. Biết tất nhiên cần có cách phòng tránh.

  • Prepared statements with parameterized queries – Các truy vấn cần được chuẩn hoá.
  • Input validation – blacklist validation and whitelist validation – Thực hiện validation chặt chẽ đầu vào
  • Principle of least privilege – Application accounts shouldn’t assign DBA or admin type access onto the database server. – Đặt quyền tối thiểu, tài khoản ứng dụng tất nhiên không thể có quyền truy cập vào dữ liệu nhạy cảm.

4. Điểm yếu của REST web services là gì?

Câu hỏi thứ 4 trong bộ câu hỏi phỏng vấn backend developer là câu hỏi liên quan tới API design. Để trả lời được câu hỏi này. Anh em cần có kinh nghiệm ở REST. Không những chỉ REST mà còn ở các kiến trúc API khác.

Khi đã có kinh nghiệm kha khá hoặc có cơ hội khác tiếp xúc với GraphQL chẳng hạn. Anh em sẽ có cái nhìn rõ hơn về điểm yếu của REST web services.

Để trả lời cho câu hỏi này, anh em có thể liệt kê ra một số nhược điểm của REST bao gồm:

  • Trường hợp không có API contract giữa client và server. Nên REST cần có tài liệu đi kèm để giải thích cụ thể những gì được viết hoặc thực hiện ở API.
  • REST web services hoạt động dựa trên HTTP nên không thể có các request bất đồng bộ (asynchronous)
  • Với kiến trúc REST, session can’t be maintained (không được duy trì lâu).

5. Giải thích API Gateway Pattern

Với backend developer ở trình độ cao, bộ câu hỏi phỏng vấn không thể không có các câu hỏi liên quan tới Software Architecture. Gateway là một trong các câu hỏi đó, trong bộ các câu hỏi phỏng vấn backend developer.

Để trả lời câu hỏi này, anh em có thể tham khảo:

An API Gateway is a server that is the single entry point into the system. It is similar to the Facade pattern from object‑oriented design. The API Gateway encapsulates the internal system architecture and provides an API that is tailored to each client. It might have other responsibilities such as authentication, monitoring, load balancing, caching, request shaping and management, and static response handling. API gateway là server và nó là điểm vào duy nhất của hệ thống. Nó tương tự như Facade Pattern trong lập trình hướng đối tượng. API Gateway đóng gói kiến trúc nội bộ và cung cấp API phù hợp cho từng client. Ngoài ra API Gateway có thể có các chức năng khác như xác thực, giám sát, cân bằng tải, cache đóng gói và quản lý các response.

API Gateway

Kieblog có bài viết cụ thể và giải thích rõ ràng hơn về API gateway ở đây. Anh em có thể đọc để hiểu sâu hơn

Tìm việc làm Backend Intern HCM trên TopDev ngay!

6. B-tree index trong hệ cơ sở dữ liệu hoạt động như thế nào?

Câu hỏi thứ 6 trong bộ câu hỏi phỏng vấn backend developer liên quan tới hệ cơ sở dữ liệu (database). Tất nhiên rồi, đã làm backend mà không biết hoặc không một lần đụng tới index thì quả thật là hết sức vô lý.

Đối với anh em có nhiều thời gian làm việc với database, với cơ sở dữ liệu lớn hoặc ít nhất là các task liên quan tới tối ưu SQL sẽ biết tới index. Tuy nhiên biết là một chuyện, nhưng nó hoạt động ra sao lại đòi hỏi thời gian để tìm tòi.

Trả lời cho câu hỏi này anh em cần biết về cây nhị phân (binary tree). B-tree tốt hơn cây nhị phân ở chỗ dữ liệu được lưu trữ trên đĩa. Việc truy cập để lấy dữ liệu trên đĩa thực sự chậm hơn so với bộ nhớ (memory). B-tree được hình dung như việc lấy hoặc tìm kiếm thông tin một cuốn sách ở trong thư viện.

Bản thân cuốn sách đó đã được đánh dấu hoặc sắp xếp các câu hỏi bắt đầu bằng A,B,C và D,E,F. Nếu cần D, ta sẽ bỏ qua một khoảng tương đối dài của A,B,C. Việc này giúp tối ưu hiệu quả tìm kiếm. B-tree cần tới logB N

7. Sự khác biệt giữa Acceptance Test và Functional Test?

Sẽ thật sự là thiếu sót to lớn nếu bỏ qua Software Testing khi phỏng vấn Backend Developer. Testing từ lâu đã là một kỹ năng cần có của mọi lập trình viên. Bất kể Front hay là Back, tất cả đều yêu cầu có kiến thức về Software Testing. Testing là công đoạn không thể thiếu giúp tạo ra một sản phẩm phần mềm tốt.

Trả lời cho câu hỏi này:

Functional testing: This is a verification activity; did we build a correctly working product? Does the software meet the business requirements? A functional test verifies that the product actually works as you (the developer) think it does. Test tính năng; Đây là hoạt động xác minh. Thông thường với các câu hỏi, chúng tôi đã xây dựng một sản phẩm chính xác chưa?. Phần mềm có đáp ứng được yêu cầu nghiệp vụ không? Sản phẩm đã đáp ứng được yêu cầu thực tế hay chỉ như người lập trình viên nghĩ?

Tiếp đến là kiểm thử chấp nhận (khác với kiểm tra tính năng)

Acceptance testing: This is a validation activity; did we build the right thing? Is this what the customer really needs? Acceptance tests verify the product actually solves the problem it was made to solve. This can best be done by the user (customer), for instance performing his/her tasks that the software assists with. Test xác nhận. Thường bắt đầu với các câu hỏi, thứ chúng ta xây dựng ra đã đúng chưa?. Đây có phải thật sự là những gì khách hàng cần tới?. Acceptance testing xác định rằng sản phẩm thực sử giải quyết được vấn đề. Việc này tốt nhất nên được thực hiện bởi khách hàng (các tác vụ của họ được phần mềm hỗ trợ)

8. Tham khảo thêm câu hỏi khác phỏng vấn backend developer

Qua bài viết này, anh em backend phần nào cũng hiểu ra rằng phỏng vấn backend developer không hề đơn giản. Trải qua nhiều các topics, các nội dung cần nắm, các kiến thức cần tìm hiểu thêm.

Mong rằng một số câu hỏi liên quan tới API Design, Software Architecture và Software Testing phần nào giúp đỡ anh em trong các đợt phỏng vấn.

Cảm ơn anh em đã đọc bài – Thank you for your time – Happy coding!

Tác giả: Kiên Nguyễn

Bạn có thể quan tâm:

Tìm việc làm IT lương cao, đãi ngộ hấp dẫn trên TopDev!

Scratch là gì? Lập trình Scratch có gì thú vị?

Lập trình Scratch

Lập trình Scratch từ lâu đã là ngôn ngữ lập trình phổ biến cho học sinh, sinh viên và các em nhỏ. Với Scratch, việc lập trình từ ban đầu được gán cho cái mác khó nhằn, khó hiểu, đơn điệu và tẻ nhạt bỗng trở thành ngôn ngữ lập trình được các em nhỏ không cần cha mẹ nói cũng vào học.

Quả không sai, cách thức tiếp cận là tất cả. Vậy điều gì làm nên sức hút của Scratch. Ví dụ tạo project với scratch như thế nào? Tất cả sẽ có trong bài viết này.

1. Lập tình Scratch là gì?

Bắt đầu với định nghĩa về lập trình Scratch, bài viết này dành cho học sinh sinh viên nên định nghĩa cũng được giải thích rõ ràng dễ hiểu hơn.

Scratch is a visual programming language that allows students to create their own interactive stories, games and animations Scratch là ngôn ngữ lập trình trực quan cho phép học sinh tạo ra các câu chuyện của họ, trò chơi và các hoạt hình tương tác của bản thân mình.

Lập trình scratch vô cùng thú vị
Nghe thôi đã thấy hấp dẫn rồi. Với lập trình Scratch, học sinh được học cách thiết kế, suy nghĩ sáng tạo, lập luận có hệ thống và cùng nhau làm việc để tạo ra dự án riêng. Scratch được tạo ra bởi nhóm Lifelong Kindergarten tại phòng thí nghiệm của MIT.

Các bạn có thể tải miễn phí Scratch tại https://scratch.mit.edu/.

  Cách tự học lập trình tốt nhất

2. Từng bước với lập trình Scratch

Để bắt đầu với lập trình scratch, truy cập trang chủ và ấn vào start creating. Các bạn cũng có thể signup (tạo tài khoản để lưu trữ các project của cá nhân mình).

lập trình scratch
Truy cập trang chủ và ấn vào Start Creating
Scratch sẽ chuyển hướng ta tới trang bắt đầu để lập trình với Scratch.

Lập trình scratch
Giao diện sau khi đã khởi tạo project tại Scratch
Trước khi bắt đầu, các bạn nên xem qua video hướng dẫn một số thao tác cơ bản và thành phần của scratch.

Lập trình scratch
Video hướng dẫn cụ thể và rõ ràng
Lập trình scratch chú trọng tới các đối tượng và lập trình animations cho các đối tượng. Đối tượng ban đầu và mặc định là chú mèo scratch. Để thêm các đối tượng khác. Ấn vào góc bên dưới bên phải màn hình.

Tham khảo việc làm Front-end hấp dẫn trên TopDev

Lập trình scratch
Góc dưới bên phải cho phép thêm nhiều hơn các đối tượng.

Sau khi đã có các đối tượng, bước tiếp theo là các thao tác, âm thanh được tuỳ chọn để lập trình. Việc lựa chọn đúng các thao tác giúp đối tượng trở nên sinh động hơn.

  50 keywords mà mọi lập trình viên java nên biết

Scratch hiện tại hỗ trợ code (trực quan không code), costumes (tuỳ chỉnh cao hơn) và Sounds (phần âm thanh cho các đối tượng)

Lập trình scratch

2.1 Các đối tượng trong Scratch

Về mặt code, hiện tại scratch hỗ trợ danh sách sau:

  • Motion (di chuyển 10 bước, xoay ngang dọc, di chuyển tới vị trí có toạ độ x và y)
  • Looks (xin chào, thay đổi kích thước, ẩn (hide), hiện (show), …
  • Sounds (âm thanh bắt đầu tới lúc kết thúc, thay đổi volume tăng hoặc giảm, …)
  • Events (khi ấn vào thì sao?, khi nhận được tin nhắn, …)
  • Control (kiểm soát, các câu lệnh cơ bản của lập trình, nếu a thì b, nếu như thế này thì thế kia, …)
  • Sensing (các sự kiện của chuột, các sự kiện chờ cho câu hỏi, câu trả lời, …)
  • Operators (các phép cộng trừ, so sánh, tính toán độ dài, …)
  • Variables (các biến tuỳ chỉnh, thiết lập dữ liệu, thay đổi các biến, …)

lập trình scratch
Các đối tượng được hỗ trợ trong khối Variables

3. Tuỳ biến, tuỳ chỉnh cao hơn với lập trình Scratch

Sau khi đã hiểu rõ và thực hành một số thành phần code được hỗ trợ bởi Scratch. Nếu các animations và lập trình cần tới tuỳ chỉnh các đối tượng. Việc tuỳ chỉnh đối tượng cho phép làm ra các đoạn code sinh động hơn, phù hợp hơn với yêu cầu.

lập trình scratchMục consumes dành cho các đối tượng tuỳ chỉnh. Cho phép chỉnh sửa màu sắc, hình dạng, kích thước các đối tượng.

Lập trình scratchThay đổi màu sắc quần của đối tượng sang màu tím.

Một thành phần khác giúp cho các video animations được lập trình trở nên tuyệt vời hơn là âm thanh. Âm thanh cũng có thể tuỳ chỉnh ở mục Sounds.

lập trình scratch

Nếu hình ảnh trong bộ sưu tập có sẵn của Scratch không phù hợp hoặc chưa đáp ứng được nhu cầu của bạn. Các bạn có thể tự tải lên các hình ảnh riêng của mình bằng nút nhấn phía bên dưới phải màn hình.

lập trình scratch
Tải lên các hình ảnh cá nhân hoặc tự xây dựng là hoàn toàn khả thi với scratch

4. Các tuỳ chỉnh khác

Scratch giúp tăng tư duy toán tức IQ, kỹ năng giải quyết tình cảm tức EQ, ngôn ngữ, sáng tạo và hợp tác với bạn bè và máy tính. Scratch luôn luôn miễn phí và được thông dịch qua hơn 70 ngôn ngữ. Các bạn có thể lựa chọn ngôn ngữ tiếng việt giúp dễ dàng hơn khi bắt đầu với Scratch

lập trình scratch
Nút nhấn quả địa cầu là khu vực để lựa chọn ngôn ngữ
lập trình scratch
Có sẵn ngôn ngữ tiếng việt giúp dễ dàng hơn khi lập trình với Scratch

Khả năng lập trình máy tính là một phần quan trọng trong học vấn của xã hội ngày nay. Khi mọi người học cách lập trình bằng Scratch, bản thân họ sẽ học được những chiến thuật quan trọng để giải quyết vấn đề, thiết kế các chương trình và truyền đạt những ý tưởng.

Chính vì vậy, không chỉ riêng tập lớp trẻ em, học sinh là nên tiếp thu với lập trình scratch. Người già, các đối tượng khác trong xã hội nếu có điều kiện cũng có thể thử sức, sáng tạo với lập trình scratch

5. Tham khảo thêm

Cảm ơn anh em đã dành thời gian – Thank you for your time to read – Happy coding!

Tác giả: Kiên Nguyễn

Xem thêm:

Xem thêm các việc làm công nghệ hấp dẫn trên TopDev

 

Giới thiệu Aspect Oriented Programming (AOP)

Aspect Oriented Programming

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

AOP là gì?

Trong khi xây dựng các chương trình ứng dụng, có rất nhiều những vấn đề liên quan đến phần mềm mà chúng ta cần quan tâm. Chẳng hạn, chúng ta xây dựng một hệ thống đăng ký tạo tài khoản cho một ngân hàng. Ngoài công việc chính cho phép người dùng có thể tạo tài khoản (core concern), hệ thống còn phải đảm bảo các vấn đề khác (cross-cutting concern) như chứng thực người dùng, kiểm tra ràng buộc, quản lý transaction, xử lý ngoại lệ, ghi log, debug, đo hiệu năng của ứng dụng,…

Logger logger = Logger.getLogger(...);
TransactionManager tm = getTransactionManager();
public void addAccount(Account account) {
    logger.info("Creating (" + account + ") Account");
    try {
        tm.beginTransaction();
        db.add(account);
        tm.commit();
    } catch (Exception) {
        tm.rollback();
        logger.error("Account creation failed");
    }
}

Như bạn thấy, logic của chương trình của chúng ta phải làm rất nhiều việc như ghi log, mở/ đóng transaction, xử lý ngoại lệ, … Khi có nhiều phương thức tương tự vậy trong ứng dụng, code chúng ta bị liên kết chặt vào nhau, duplicate code, phân mảnh nhiều nơi, khó khăn khi sửa đổi thay thêm logic mới, … Để giải quyết vấn đề này, chúng ta có thể sử dụng kỹ thuật AOP.

Aspect Oriented Programming

AOP là từ viết tắt của Aspect Oriented Programming, dịch ra tiếng Việt là “phương pháp lập trình hướng khía cạnh”. AOP là một kỹ thuật lập trình cho phép phân tách chương trình thành cách module riêng rẽ, không phụ thuộc nhau. Khi hoạt động, chương trình sẽ kết hợp các module lại để thực hiện các chức năng nhưng khi sửa đổi chức năng thì chỉ cần sửa đổi trên một module cụ thể.

AOP còn được gọi là Aspect Oriented Software Development (AOSD) là một nguyên tắc thiết kế, giúp tách rời các yêu cầu hay các vấn đề được quan tâm (separation of concerns) trong chương trình thành các thành phần độc lập và từ đó tăng tính uyển chuyển cho chương trình. Trong Separation of concerns, người ta cho rằng những vấn đề tương tự nhau nên được giải quyết trong một unit of code. Khi lập trình thủ tục (functional programming), một unit of code là một function/ method, còn trong lập trình hướng đối tượng (OOP) thì unit of code là một class.

  Lập trình hướng đối tượng (OOPs) trong Java

  Javascript Prototype là gì?

aspect orientedprogramming aop in java

Trong AOP, chương trình của chúng ta được chia thành 2 loại concern:

  • Core concern/ Primary concern: là requirement, logic xử lý chính của chương trình.
  • Cross-cutting concern: là những logic xử lý phụ cần được thực hiện của chương trình khi core concern được gọi như security, logging, tracing, monitoring, …

Một số thuật ngữ khác trong AOP:

  • Joinpoint: là một điểm trong chương trình, là những nơi có thể được chèn những cross-cutting concern. Chẳng hạn chúng ta cần ghi log lại sau khi chạy method nào đó thì điểm ngay sau method đó được thực thi gọi là một Jointpoint. Một Jointpoint có thể là một phương thức được gọi, một ngoại lệ được throw ra, hay một field được thay đổi.
  • Pointcut: có nhiều cách để xác định Joinpoint, những cách như thế được gọi là Pointcut. Nó là các biểu thức được sử dụng để kiểm tra nó có khớp với các Jointpoint để xác định xem Advice có cần được thực hiện hay không.
  • Advice: những xử lý phụ (crosscutting concern) được thêm vào xử lý chính (core concern), code để thực hiện các xử lý đó được gọi Advice. Advice được chia thành các loại sau:
    • Before: được thực hiện trước join point.
    • After: được thực hiện sau join point.
    • Around: được thực hiện trước và sau join point.
    • After returning : được thực hiện sau join point hoàn thành một cách bình thường.
    • After throwing : được thực hiện sau khi join point được kết thúc bằng một Exception.
  • Aspect: tương tự như một Java class. Một Aspect đóng gói toàn bộ cross-cutting concern và có thể chứa các JointPoint, PointCut, Advice.
  • Target Object : là những đối tượng mà advice được áp dụng.

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

Một vài cross-cutting concern thường thấy trong ứng dụng:

  • Logging
  • Monitor
  • Access control
  • Error handling
  • Transaction management
  • Session management
  • Input/output validation

Weaving là gì?

Weaving là gì?

Về cơ bản Weaving (đan/ dệt) là quá trình liên kết các thành phần aspect và non-aspect của một chương trình để tạo ra đầu ra mong muốn.

Có một vài cách khác nhau giữa các hệ thống AOP về cách tạo ra Weaving. Có thể chia làm các loại Weaving: Compile-time weaving (static weaving), Load-Time Weaving và Run-time weaving (dynamic weaving).

  • Compile-time weaving :
    • Pre-Compile Weaving : sử dụng bộ tiền xử lý (pre-processor) để combine code của aspect và code non-aspect lại với nhau trước khi code được biên dịch thành byte code Java (.class).
    • Post-Compile Weaving / Binary weaving : cách này dùng để inject code của aspect vào những tập tin .class của Java đã được compile.
  • Load-Time Weaving : cách này dùng để inject code của aspect khi class cần sử dụng aspect được load vào JVM, nghĩa là trong khi ứng dụng đang chạy.
  • Run-time weaving: thực hiện weaving và unweaving code của aspect và non-aspect tại run-time.

Static weaving

Static weaving là quá trình combine code của aspect và code non-aspect lại với nhau trước khi code được biên dịch thành Java byte code (.class) bằng cách sử dụng bộ tiền xử lý (pre-processor). Do đó, code gốc chỉ được thay đổi một lần tại thời gian biên dịch (compile). Hiệu suất của code được combine này tương đương với code được viết theo truyền thống.

Hạn chế của phương pháp Static weaving là khó khăn trong việc xác định code của aspect sau này hoặc thực hiện thay đổi đối với code của aspect. Mỗi khi code của aspect bị thay đổi, tất cả tất cả code sử dụng aspect phải được biên dịch lại.

Dynamic weaving

Dynamic weaving khắc phục một số hạn chế gặp phải khi weaving được thực hiện tại thời gian biên dịch (Compile-time weaving/ Static weaving). Có thể tránh được yêu cầu biên dịch lại (recompilation), triển khai lại (redeployment) và khởi động lại (restart) bằng cách thực hiện quy trình weaving trong thời gian chạy (run-time weaving).

Có một chút khác biệt giữa load-time và run-time weaving.

  • Load-time weaving chỉ đơn giản là trì hoãn quá trình weaving cho đến khi các lớp được nạp bởi class loader. Cách tiếp cận này yêu cầu sử dụng một weaving class loader hoặc thay thế class loader bằng một loader khác. Hạn chế là load-time tăng lên và thiếu quyền truy cập vào các aspect trong khi chạy.
  • Run-time weaving là quá trình weaving và unweaving tại run-time. Cách tiếp cận này yêu cầu các cơ chế mới để can thiệp vào việc tính toán chạy.

Các AOP Framework khác nhau có cách thực hiện dynamic weaving khác nhau. Trong khi AspectWerkz sử dụng sửa đổi byte code thông qua chức năng cấp JVM và kiến ​​trúc “hotswap” để thực hiện weaving các lớp tại run-time, thì Spring AOP Framework dựa trên các proxy thay vì các class loader hoặc dựa vào các đối số JVM.

Dynamic weaving cho phép tăng tốc các giai đoạn thiết kế và kiểm thử trong phát triển phần mềm, vì các aspect mới có thể được thêm vào hoặc các aspect hiện tại có thể được thay đổi mà không cần biên dịch lại và triển khai lại các ứng dụng. Tuy nhiên, một nhược điểm lớn là hiệu suất giảm, vì weaving xảy ra tại run-time.

Cài đặt AOP trong Java như thế nào?

Một vài ý tưởng để implement AOP trong chương trình của chúng ta:

  • Class-weaving : như đã đề cập ở phần trên.
  • Proxy-based : bạn có thể tưởng tượng nó như là một ví dụ sử dụng >Decorator Pattern. Sử dụng công cụ mã hóa byte code của một số thư viện như JDK proxy, CGLib proxy, chúng ta có thể chặn các lệnh gọi hàm và thêm code của riêng mình để được thực thi trước.
    • JDK proxy : đây là cách đơn giản nhất, nhưng chỉ có thể xử lý với các phương thức public được gọi, không thể xử lý các cuộc gọi nội bộ (các cuộc gọi bắt nguồn từ chính lớp đó).
    • CGLib proxy : yêu cầu chỉnh sửa byte code bị giới hạn và có thể xử lý các lời gọi phương thức private, nhưng vẫn không thể xử lý truy cập thuộc tính trực tiếp.
  • Sử dụng các thư viện sau: Google Guice, AspectJ, Spring AOP.
spring aop process

Ví dụ tự xây dựng một AOP framework

Trong ví dụ bên dưới chúng ta sẽ tự viết code để tạo AOP Framework sử dụng JDK Proxy mà không cần sử dụng bất cứ một thư viện thứ ba nào (third-party libraries).

Để xử dụng JDK Proxy chúng ta thực hiện các bước sau:

  • Tạo Invocation Handler: class này phải implemenet java.lang.reflect.InvocationHandler. InvocationHandler là interface được thực hiện bởi trình xử lý lời gọi (invocation handler) của một proxy instance. Khi một phương thức được gọi trên một proxy instance, lời gọi phương thức được mã hóa và gửi đến phương thức gọi của invocation handler của nó.
  • Tạo Proxy Instance : sử dụng phương thức Proxy.newProxyInstance() được cung cấp bởi factory method java.lang.reflect.Proxy.

Ví dụ: chúng ta cần thêm một vài xử lý trước và sau khi các phương thức trong class AccountService được gọi.

aspect orientedprogramming aop

Account.java

package com.gpcoder.aop.account;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class Account {

    private String owner;
    private String currency;
    private int balance;
}

AccountService.java

package com.gpcoder.aop.account;

public interface AccountService {

    void addAccount(Account account);

    void removeAccount(Account account);

    int getSize();
}

AccountServiceImpl.java

package com.gpcoder.aop.account;

import java.util.ArrayList;
import java.util.List;

public class AccountServiceImpl implements AccountService {

    private List<Account> accounts = new ArrayList<>();

    @Override
    public void addAccount(Account account) {
        System.out.println("addAccount: " + account);
        accounts.add(account);
    }

    @Override
    public void removeAccount(Account account) {
        System.out.println("removeAccount: " + account);
        accounts.remove(account);
    }

    @Override
    public int getSize() {
        System.out.println("getSize: " + accounts.size());
        return accounts.size();
    }
}

AbstractHandler.java

package com.gpcoder.aop.handler;

import java.lang.reflect.InvocationHandler;

public abstract class AbstractHandler implements InvocationHandler {

    private Object targetObject;

    public void setTargetObject(Object targetObject) {
        this.targetObject = targetObject;
    }

    public Object getTargetObject() {
        return targetObject;
    }
}

BeforeHandler.java

package com.gpcoder.aop.handler;

import java.lang.reflect.Method;

/**
* The class BeforeHandler provides a template for the before execution
*/
public abstract class BeforeHandler extends AbstractHandler {

    /**
     * Handles before execution of actual method.
     */
    public abstract void handleBefore(Object proxy, Method method, Object[] args);

    /*
     * (non-Javadoc)
     *
     * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object,
     * java.lang.reflect.Method, java.lang.Object[])
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        handleBefore(proxy, method, args);
        return method.invoke(getTargetObject(), args);
    }
}

BeforeHandlerImpl.java

package com.gpcoder.aop.handler.impl;

import java.lang.reflect.Method;

import com.gpcoder.aop.handler.BeforeHandler;

/**
 * This class provides implementation before actual execution of method.
 */
public class BeforeHandlerImpl extends BeforeHandler {

    @Override
    public void handleBefore(Object proxy, Method method, Object[] args) {
        // Provide your own cross cutting concern
        System.out.println("Handling before actual method execution");
    }
}

AfterHandler.java

package com.gpcoder.aop.handler;

import java.lang.reflect.Method;

public abstract class AfterHandler extends AbstractHandler {

    /**
     * Handles after the execution of method.
     */
    public abstract void handleAfter(Object proxy, Method method, Object[] args);

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = method.invoke(getTargetObject(), args);
        handleAfter(proxy, method, args);
        return result;
    }
}

AfterHandlerImpl.java

package com.gpcoder.aop.handler.impl;

import java.lang.reflect.Method;

import com.gpcoder.aop.handler.AfterHandler;

/**
 * This class provides an implementation of business logic which will be
 * executed after the actual method execution.
 */
public class AfterHandlerImpl extends AfterHandler {

    @Override
    public void handleAfter(Object proxy, Method method, Object[] args) {
        // Provide your own cross cutting concern
        System.out.println("Handling after actual method execution");
        System.out.println("---");
     }
}

ProxyFactory.java

package com.gpcoder.aop.handler;

import java.lang.reflect.Proxy;
import java.util.List;

/**
 * A factory for creating Proxy objects.
 */
public class ProxyFactory {

    private ProxyFactory() {
        throw new UnsupportedOperationException();
    }

    public static Object getProxy(Object targetObject, List<AbstractHandler> handlers) {
        if (handlers != null && !handlers.isEmpty()) {
            Object proxyObject = targetObject;
            for (AbstractHandler handler : handlers) {
                handler.setTargetObject(proxyObject);
                proxyObject = Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
                        targetObject.getClass().getInterfaces(), handler);
            }
            return proxyObject;
        }

        return targetObject;
    }
}

AspectOrientedProgrammingInJdkExample.java

package com.gpcoder.aop;

import java.util.ArrayList;
import java.util.List;

import com.gpcoder.aop.account.Account;
import com.gpcoder.aop.account.AccountService;
import com.gpcoder.aop.account.AccountServiceImpl;
import com.gpcoder.aop.handler.AbstractHandler;
import com.gpcoder.aop.handler.ProxyFactory;
import com.gpcoder.aop.handler.impl.AfterHandlerImpl;
import com.gpcoder.aop.handler.impl.BeforeHandlerImpl;

/**
 * This class to verify an AOP example using JDK proxy.
 */
public class AspectOrientedProgrammingInJdkExample {

    public static void main(String[] args) {

        List<AbstractHandler> handlers = new ArrayList<>();
        handlers.add(new BeforeHandlerImpl());
        handlers.add(new AfterHandlerImpl());

        AccountService proxy = (AccountService) ProxyFactory.getProxy(new AccountServiceImpl(), handlers);
        Account account = new Account("gpcoder", "USD", 100);
        proxy.addAccount(account);
        proxy.getSize();
        proxy.removeAccount(account);
        proxy.getSize();
    }
}

Output của chương trình:

Handling before actual method execution
addAccount: Account(owner=gpcoder, currency=USD, balance=100)
Handling after actual method execution
---
Handling before actual method execution
getSize: 1
Handling after actual method execution
---
Handling before actual method execution
removeAccount: Account(owner=gpcoder, currency=USD, balance=100)
Handling after actual method execution
---
Handling before actual method execution
getSize: 0
Handling after actual method execution
---

Lợi ích của AOP là gì?

  • Tăng hiệu quả của Object-orented programming (OOP).
  • AOP không phải dùng để thay thế OOP mà để bổ sung cho OOP, nơi mà OOP còn thiếu sót trong việc tạo những ứng dụng thuộc loại phức tạp.
  • Tăng cường tối đa khả năng tái sử dụng của mã nguồn.
  • Đảm bảo >Single responsibility principle: mỗi một module chỉ làm cái mà nó cần phải làm.
  • Tuân thủ nguyên tắc “You aren’t gonna need it – >YAGNI” – chúng ta chỉ cài đặt những thứ chúng ta thực sự cần, không bao giờ làm trước.
  • Module hóa ở mức tiến trình/ chức năng.
  • Code gọn gàng hơn do tách biệt phần xử lý chính và phần xử lý liên quan.
  • Chức năng chính của chương trình không cần biết đến các chức năng phụ khác.
  • Các chức năng phụ có thể được thêm thắt, bật tắt tại thời điểm run-time tùy theo yêu cầu.
  • Các thay đổi nếu có đối với các chức năng phụ sẽ không ảnh hưởng đến chương trình chính.
  • Hệ thống sẽ uyển chuyển và giảm thiểu tính phụ thuộc lẫn nhau của các module.
Bài viết gốc được đăng tải tại gpcoder.com

Xem thêm:

Xem thêm công việc CNTT hấp dẫn trên TopDev

Xử lý bất đồng bộ với Promise.all trong JavaScript

promise in java

Anh em lập trình viên JavaScript chắc không xa lạ gì với Promise hay async/await trong việc xử lý các tác vụ bất đồng độ trong ứng dụng của mình; tuy vậy trong thực tế dự án có nhiều bài toán cần không chỉ 1 Promise và cần handle (xử lý) kết quả trả về trong từng Promise con, lúc này thứ chúng ta cần là Promise.all và 1 vài thứ tốt hơn thế. Bài viết này mình sẽ chia sẻ cùng các bạn cách sử dụng Promise.all trong những bài toán cụ thể ở dự án mình từng trải qua.

Nhắc lại cú pháp Promise

Trước hết cùng nhắc lại cú pháp Promise cũng như async/await cho các bạn đỡ quên nhé (lưu ý là async/await được thêm vào từ ES8 nhé).

let promise = new Promise(function(resolve, reject) {
  setTimeout(() => resolve("done!"), 1000);

});
// resolve runs the first function in .then
promise.then(
  result => alert(result), // shows "done!" after 1 second
  error => alert(error) // doesn't run
);
async function f() {

  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("done!"), 1000)
  });

  let result = await promise; // wait until the promise resolves (*)

  alert(result); // "done!"
}

2 ví dụ trên là cách sử dụng Promise hay async/await để thực hiện việc chờ 1 xử lý bất đồng bộ thực hiện xong, nhận kết quả trả về để thực hiện 1 hành động nào đó – cũng khá dễ hiểu đúng không. Vậy nếu bài toán của chúng ta là cần chờ 2 hành động bất đồng bộ (ví dụ như cần call 2 API lên server) thực hiện xong để lấy kết quả thì sẽ cần làm gì? JS cung cấp cho chúng ta Promise.all.

  5 thủ thuật hay với Javascript Promise bạn cần biết!

Promise.all

Promise.all([Promise1, Promise2, Promise3])
  .then((result) => {
    console.log(result);
  })
  .catch((error) => console.log(`Error in promises ${error}`));

Promise1, Promise2 và Promise3 là những promise, bản thân Promise.all cũng là 1 promise. Vậy nó khác gì với việc chạy riêng lẻ 3 promise từ 1-3 một cách độc lập. Đầu tiên thì trong Promise.all, cả 3 Promise1-3 sẽ được thực hiện đồng thời, không cái nào cần chờ cái nào, vì thế giảm được thời gian chờ đợi và đương nhiên là tăng performance. Tiếp theo chúng ta cần lưu ý, nếu 1 trong 3 Promise1-3 đẩy ra lỗi (reject) thì Promise sẽ ngay lập tức dừng lại và nhảy vào catch chứ không thực hiện tiếp các promise khác. Trong trường hợp các task con thực hiện thành công thì Promise.all cũng sẽ trả về resolve với kết quả là 1 mảng chứa tất cả các resolve của task con.

Việc làm JavaScript Hồ Chí Minh dành cho bạn!

Đến đây chúng ta vẫn thấy quen thuộc đúng không, thực tế Promise.all được sử dụng thường xuyên trong các bài toán thực tế dự án. Mặc dù vậy sẽ có 1 số vấn đề khi sử dụng Promise.all như sau:

  • Làm sao để tạo 1 mảng Promise sử dụng map
  • Nếu muốn tất cả các Promise con thực hiện xong mà không bị dừng bị 1 trong các Promise khác thì làm sao?
  • Nếu muốn chỉ 1 trong các Promise con thực hiện xong (resolve) là hủy các Promise còn lại thì làm sao?
  • Nếu muốn chỉ 1 trong các Promise con trả về (bất kể resolve hay reject) là hủy các Promise còn lại thì làm sao?

Chúng ta cùng đi giải quyết các câu hỏi trên nhé.

Promise.all với map()

Một bài toán cũng hay gặp với Promise.all là việc sử dụng nó kết với với map nhằm tạo ra 1 group các xử lý bất đồng bộ theo mảng đầu vào. Chẳng hạn như bạn cần gửi email cho n users có sẵn trong 1 mảng dữ liệu; lúc này chúng ta có thể sử dụng hàm map() để tạo ra mảng promise con làm tham số đầu vào cho Promise.all. Ví dụ như dưới đây:

const timeOut = (t) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(`Completed in ${t}`);
    }, t);
  });
};

const durations = [1000, 2000, 3000];

Promise.all(durations.map((duration) => timeOut(duration))).then((response) =>
  console.log(response)
);

Tham khảo tuyển dụng javascript lương cao trên TopDev

Promise.allSettled

Promise.allSettled([
  Promise.reject("This failed."),
  Promise.reject("This failed too."),
  Promise.resolve("Ok I did it."),
  Promise.reject("Oopps, error is coming."),
]).then((res) => {
  console.log(`Here's the result: `, res);
});

Kết quả trả về:

[
  { status: "rejected", reason: "This failed." },
  { status: "rejected", reason: "This failed too." },
  { status: "fulfilled", value: "Ok I did it." },
  { status: "rejected", reason: "Oopps, error is coming." },
];

JavaScript cung cấp cho chúng ta Promise.allSettled để giải quyết vấn đề đầu tiên của Promise.all. Promise.allSettled trả về 1 Promise mới mà ở đó nó sẽ chờ tất cả các task con thực hiện xong, không kể có hoàn thành (resolve) hay bị reject. Kết quả trả về là 1 mảng theo thứ tự các Promise con truyền vào, mỗi object chứa status (trạng thái) của promise cùng giá trị trả về value hay reason (lí do) khi bị reject. Tất nhiên Promise.allSettled sẽ cần nhiều thời gian xử lý hơn so với Promise.all, tuy nhiên nó đảm bảo tất cả Promise được thực hiện.

>>> Xem thêm: Tìm hiểu phương thức slice của mảng trong JavaScript

Promise.race và Promise.any

Giả sử chúng ta có 2 bài toán như sau, các bạn hãy xem và lựa chọn các dùng nào của Promise nhé.

  • Bài toán 1: có 3 API get thông tin thời tiết và trả về kết quả như nhau, do vậy chỉ cần gọi 1 trong 3 API, cái nào có kết quả là được; không cần gọi tất cả 3 cái. Chúng ta sẽ làm thế nào?
  • Bài toán 2: chức năng upload cần upload file lên 3 server khác nhau và phải đảm bảo việc upload thực hiện thành công trên cả 3 server, nếu 1 trong 3 task fail thì dừng luôn 2 task còn lại.

Để giải quyết 2 bài toán trên, JavaScript cung cấp thêm cho chúng ta 2 function nữa là Promise.race và Promise.any. Promise.race và Promise.any có điểm chung là đều sẽ hoàn thành (resolve) khi 1 trong các promise con được thực hiện xong. Như ví dụ bài toán 1, nếu có 1 API get thông tin thời tiết hoàn thành xong thì nếu dùng Promise.race hoặc Promise.any, 2 API get thông tin thời tiết còn lại sẽ không cần thực hiện nữa.

Điểm khác nhau giữa race và any là ở trường hợp reject: any sẽ chỉ reject khi tất cả các promise con reject (hay không có promise nào trả về resolve); còn race sẽ reject khi chỉ cần 1 promise con reject. Điều này giúp Promise.race giải quyết bài toán thứ 2 ở trên. Khi có 1 trong 3 task upload file lên server thất bại thì sẽ dừng luôn 2 task còn lại.

Chúng ta có thể tổng kết họ hàng nhà Promise.all như sau:

Promise

Kết bài

Như vậy chúng ta đã đi qua hết được các phương thức xử lý bất đồng bộ Promise.all cùng cách sử dụng chúng trong từng bài toán cụ thể. Trong thực tế dự án sẽ có nhiều trường hợp các bạn sẽ vận dụng kết hợp các function khác nhau, có thể là Promise.all trong Promise.all chẳng hạn. Vì thế hãy nắm vững cách case sử dụng từng function trên nhé. Hy vọng bài viết của mình hữu ích dành cho các bạn.

Tác giả: Phạm Minh Khoa

Xem thêm:

Tìm việc làm IT mới nhất trên TopDev

Kiến trúc hệ thống là gì?

kiến trúc hệ thống

Với 1 hệ thống bất kỳ, việc xây dựng kiến trúc luôn là bước đầu tiên và quan trọng nhất quyết định tính khả thi của cả hệ thống. Đầu ra của bước thiết kế hệ thống sẽ giải quyết nhu cầu đề ra của người dùng, đồng thời là bước quan trọng để bắt đầu việc xây dựng các ứng dụng cũng như cách giao tiếp giữa các phần trong hệ thống. Bài viết hôm nay mình sẽ cùng các bạn tìm hiểu Kiến trúc hệ thống là gì và tại sao nó lại có vai trò quyết định sự thành công của 1 dự án nhé.

Kiến trúc hệ thống là gì?

1 hệ thống bất kỳ nào đó sẽ luôn có 1 kiến trúc vật lý của riêng mình, từ những website đến các ứng dụng trên thiết bị di động, hầu hết chúng đều cần phải giao tiếp với server để thực hiện các thao tác lấy dữ liệu, cập nhật chỉnh sửa thông tin dữ liệu.

Để dễ hình dung trong bài viết này mình sẽ nhắc đến 1 hệ thống web và ứng dụng mobile sử dụng mô hình client-server như hình dưới đây.

kiến trúc hệ thống

Kiến trúc hệ thống, hiểu đơn giản đó là cách tổ chức của 1 hệ thống, bao gồm tất cả các thành phần, cách chúng tương tác với nhau, môi trường mà chúng hoạt động và các nguyên tắc được sử dụng để thiết kế ra phần mềm trong hệ thống. Như ở hệ thống trên, chúng ta có thể dễ thấy 2 phần chính là CLIENT và SERVER, trong đó:

  • CLIENT: các trình duyệt web, các ứng dụng trên desktop hay smartphone truy cập để lấy và update dữ liệu bằng cách tương tác với SERVER (thông qua API)
  • SERVER: máy chủ, hiểu đơn giản đó là 1 máy tính với CPU, RAM, ổ cứng và các phần mềm phục vụ cho việc phát triển web.

  [Update] 5 xu hướng dẫn dắt “làn sóng” công nghệ trong năm 2024

  Giới thiệu về JAMstack – kiến trúc phát triển web hiện đại

Vai trò của kiến trúc hệ thống

Kiến trúc hệ thống như 1 bản thiết kế cho 1 ngôi nhà, nó cung cấp 1 sự trừu tượng để quản lý độ phức tạp của hệ thống và thiết lập 1 cơ chế giao tiếp giữa các thành phần. Vai trò của kiến trúc hệ thống có thể được list ra như sau:

  • Xác định 1 giải pháp có cấu trúc để đáp ứng tất cả các yêu cầu kỹ thuật và vận hành
  • Tối ưu hóa về mặt hiệu suất và bảo mật
  • Tác động đến chất lượng, hiệu suất và sự thành công chung của sản phẩm cuối cùng
  • Quyết định đến cách xây dựng và phát triển phần mềm bao gồm việc lựa chọn ngôn ngữ, thư viện, framework sử dụng hay kể cả giao diện người dùng.

Xem thêm việc làm Back-end hấp dẫn trên TopDev

kiến trúc hệ thống

Một số kiến trúc hệ thống hay sử dụng

Kiến trúc nguyên khối (Monolith)

Kiến trúc này tạo ra 1 đơn vị phần mềm không thể chia tách, các thành phần khác nhau của ứng dụng được kết hợp thành 1 chương trình duy nhất trên 1 nền tảng duy nhất. Các thành phần trong kiến trúc nguyên khối thường bao gồm: cơ sở dữ liệu (database), giao diện phía người dùng (client) và ứng dụng phía máy chủ (server)

kiến trúc hệ thống

Một kiến trúc nguyên khối (Monolith) sẽ thích hợp thực hiện cho các công ty nhỏ, các thành phần được kết nối với nhau và phụ thuộc nhau giúp phần mềm được khép kín. Ưu điểm của nó là tiết kiệm được thời gian phát triển và triển khai 1 cách đơn giản; hiệu suất ứng dụng cũng cao hơn do các thành phần giao tiếp với nhau 1 cách trực tiếp, đồng thời bộ nhớ được chia sẻ. Tuy vậy, nhược điểm của kiến trúc này là càng theo thời gian, khi lượng code, chức năng càng lớn thì hệ thống càng trở lên cồng kềnh và kém linh hoạt; chưa kể nếu 1 thành phần nhỏ trong cả hệ thống bị lỗi sẽ kéo theo việc toàn bộ hệ thống không thể hoạt động được.

Kiến trúc Microservice

Như hình ở trên, kiến trúc microservice thường được đưa ra so sánh với Monolith cho việc giải quyết các vấn đề mà kiến trúc nguyên khối gặp phải. Microservice là 1 loại kiến trúc hệ thống hướng dịch vụ, tập trung vào việc xây dựng 1 loạt các thành phần có khả năng tự quản lý tạo nên ứng dụng. Cách tiếp cận microservice đã trở thành 1 xu hướng trong những năm gần đây khi ngày càng có nhiều công ty áp dụng, sử dụng nhiều công nghệ DevOps. Các công ty lớn như Netflix, Amazon, Twitter, Paypal là những công ty đã phát triển chuyển đổi từ cách tiếp cận Monolith sang Microservice.

Ưu điểm lớn nhất của microservice chính là việc có thể dễ dàng triển khai, thử nghiệm các ứng dụng nhỏ 1 cách độc lập mà không làm ảnh hưởng đến hệ thống hiện có. Các service khác nhau cũng không bị tình trạng phải chờ đợi nhau hoàn thành mới có thể triển khai và chạy được, nhờ đó rủi ro khi triển khai cũng được giảm xuống trên đơn vị 1 service con. Với microservice, hệ thống của chúng ta có khả năng mở rộng theo chiều ngang, tức là dễ dàng nâng cấp, bổ sung phần cứng cho từng service với chi phí vừa phải, không cần đầu tư vào 1 máy có cấu hình cao như kiến trúc monolith để chạy hệ thống.

Tuy vậy thì hệ thống nào cũng có nhược điểm, với microservice đó là sự phức tạp khi chia ứng dụng thành các service nhỏ độc lập khiến cần nhiều công việc quản lý hơn cho từng service đó. Ngoài ra tính bảo mật cũng là 1 vấn đề khi giờ đây các API sẽ phải public ra bên ngoài để các service khác có thể gọi tới, điều đó khiến nguy cơ bị tấn công cũng cao hơn.

kiến trúc hệ thống

Kiến trúc hướng dịch vụ (SOA)

SOA – Service-Oriented Architecture là kiểu kiến trúc phần mềm dùng để chỉ ứng dụng bao gồm các tác nhân phần mềm rời rạc và lỏng lẻo thực hiện 1 chức năng cần thiết.

Ứng dụng trong SOA có thể được thiết kế và xây dựng theo kiểu module hóa , tích hợp dễ dàng và có thể sử dụng lại.

kiến trúc hệ thống

SOA có thể xem như 1 là kiến trúc nằm giữa Monolith và Microservice, khi nó được tạo thành từ các thành phần độc lập nhưng gần như không giao tiếp (hoặc rất ít) với các thành phần khác kiểu trong microservice. Cách chia module của SOA cũng sẽ khác với cách tiếp cận dạng service trong microservice. 

Kết bài

Như vậy chúng ta đã cùng đi qua khái niệm cơ bản về kiến trúc hệ thống cũng như 1 số kiến trúc hệ thống thường được áp dụng hiện nay. Đây là 1 phần khó trong lĩnh vực kỹ thuật lập trình nói riêng và kỹ sư công nghệ nói chung, vì thế nếu bạn yêu thích phần này, hãy tìm hiểu sâu thêm về các kiến trúc hệ thống mà các công ty đang áp dụng nhé. Hy vọng bài viết hữu ích dành cho bạn và hẹn gặp lại trong các bài viết tiếp theo của mình.

Tác giả: Phạm Minh Khoa

Xem thêm:

Cập nhật it jobs Developer lương cao mới nhất TopDev

[Update] 5 xu hướng dẫn dắt “làn sóng” công nghệ trong năm 2024

Tổng hợp 5 xu hướng dẫn dắt “làn sóng” công nghệ trong năm 2023

Công nghệ ngày càng phát triển với nhịp độ nhanh và cải tiến không ngừng. Cập nhật và đón đầu các xu hướng công nghệ mới là cơ hội cho các developer lên kế hoạch, nắm bắt thời cơ, để vươn lên mạnh mẽ trên con đường sự nghiệp. Hãy cùng TopDev điểm qua 5 công nghệ chính sẽ dẫn dắt “làn sóng” công nghệ trong năm 2024 này nhé!

Blockchain & Web3

Các hệ sinh thái phi tập trung Blockchain & Web3 sẽ phát triển mạnh mẽ hơn trong năm 2024 bởi những trải nghiệm an toàn, minh bạch mà chúng mang lại. 

Blockchain sẽ giúp người dùng tin tưởng vào những thứ được lưu trữ trên mạng lưới và ngăn chặn việc thay đổi hay giả mạo thông tin. Cùng với đó, Web3 sẽ cho phép người dùng trao đổi thông tin và giao dịch dựa trên công nghệ blockchain, ngoài ra nó còn giúp ngăn chặn sự phụ thuộc của người dùng vào các cá nhân hay tổ chức trung gian.

Tuy vẫn còn nhiều tranh cãi xung quanh khả năng ứng dụng và tính minh bạch của blockchain & web3, nhưng không thể phủ nhận những giải pháp mà chúng có thể mang lại cho người dùng. Dự đoán năm 2024 sẽ là một năm phát triển mạnh mẽ hơn nữa của công nghệ này.

>>> Bạn có thể tham khảo thêm về tiềm năng ứng dụng thực tế của blockchain & web3

Tham khảo việc làm Blockchain hấp dẫn trên TopDev

5G & IoT

Các công nghệ như blockchain, metaverse sẽ không phát triển hết mức do khả năng kết nối hạn chế. Các công nghệ này cần phải truyền tải một lượng thông tin khổng lồ cùng một lúc, vậy nên sự phát triển của 5G là vô cùng cần thiết. Cùng với đó, IoT (Internet of Thing) sẽ kết nối tất cả mọi thứ lại với nhau dễ dàng nhờ vào mạng lưới cảm biến, thiết bị và cơ sở hạ tầng thông minh. 

>>> Đón đầu xu hướng với bài viết về tình hình hiện tại và tương lai của IoT trong năm 2023

5G & IoT

Cùng với sự phát triển của IoT, một khái niệm mới cũng được cho ra đời có tên là IoV (Internet of vehicle). IoV là mạng lưới kết nối người đi bộ, người đi ô tô, và các bộ phận khác của cơ sở hạ tầng đô thị, nó là một phần của thành phố thông minh. IoV cố gắng làm cho giao thông trở nên tự chủ, an toàn, nhanh chóng và hiệu quả hơn, giảm thiểu tài nguyên sử dụng và tác động tiêu cực tới môi trường.

>>> Bạn có thể tìm hiểu sâu hơn về IoV qua bài viết IoV (Internet of vehicle) là gì? Kiến trúc IoV

Trí tuệ nhân tạo (AI) và máy học (ML)

Trí tuệ nhân tạo AI sẽ tiếp tục bùng nổ trong năm 2024 nhờ khả năng thích ứng nhanh chóng với nhu cầu phát triển không ngừng trong bối cảnh kinh doanh hiện nay. Doanh nghiệp có thể tận dụng AI để tạo ra các sản phẩm, dịch vụ thông minh hơn, cải tiến quy trình sản xuất và làm được nhiều điều hơn nữa.

Song song với đó, Machine Learning (ML) hay máy học là một nhánh của trí tuệ nhân tạo. Hoạt động bằng khả năng cải thiện chính bản thân chúng dựa trên dữ liệu mẫu (training data) hoặc dựa vào kinh nghiệm (những gì đã được học). Machine Learning được áp dụng trong mọi lĩnh vực và vượt trội hơn hẳn con người.

>>> Tìm hiểu sâu hơn về Machine Learning trong bài viết Machine Learning là gì? Và những ứng dụng của AI vào trong lĩnh vực y tế

Thực tế ảo (VR) và Thực tế ảo tăng cường (AR)

ar vr

Công nghệ Thực tế ảo (VR) và Thực tế ảo tăng cường (AR) sẽ mở đường cho các mô hình kinh doanh mới nhờ khả năng độc đáo “thực tế không giới hạn”. Bắt đầu từ lĩnh vực game sau đó đến việc ứng dụng trong các mô hình giáo dục, chăm sóc sức khỏe và tiến xa hơn là tạo môi trường tương tác mở rộng với thực tế hỗn hợp.

Đây chắc chắn sẽ là những công nghệ cốt lõi định hình thế giới trong tương lai.

>>> Xem thêm bài viết về Thực tế ảo (VR) và Thực tế ảo tăng cường (AR) tại đây.

Điện toán đám mây (Cloud Computing)

Trong tương lai, điện toán đám mây sẽ là “đầu tàu” tiên phong trong lĩnh vực công nghệ bên cạnh các công nghệ như metaverse, AI, 5G & IoT. Với dịch vụ điện toán đám mây, người dùng có thể truy cập thông tin từ bất cứ đâu và bất cứ khi nào mà chỉ thông qua một trung tâm kỹ thuật số. 

Điện toán đám mây sẽ giúp ích rất nhiều cho doanh nghiệp trong việc phát triển trí tuệ nhân tạo (AI) và máy học (ML). Vấn đề không gian lưu trữ cho các thuật toán phức tạp sẽ được giải quyết triệt để với công nghệ này. 

Hãy cùng TopDev xem qua những cải tiến của Google trên nền tảng Google Cloud để hướng tới hỗ trợ tất cả dữ liệu phi cấu trúc qua bài viết: Google Cloud hướng tới hỗ trợ tất cả dữ liệu phi cấu trúc

Đây là top 5 xu hướng sẽ dẫn dắt “làn sóng” công nghệ trong năm 2024 mà TopDev đã tổng hợp được. Hy vọng anh em Dev sẽ nắm bắt thật tốt để khai thác và chuẩn bị cho các chiến lược tốt hơn trong năm sau.

Xem thêm:

Tìm kiếm việc làm IT mới nhất tại TopDev!

Embedded Developer là gì? Cần học gì để trở thành Embedded Developer

Embedded Developer là gì? Cần học gì để trở thành Embedded Developer

Những năm trở lại đây, cứ nhắc đến công nghệ là người ta lại nhắc đến 4.0, nhắc đến IoT, smartthing, … Với lĩnh vực lập trình, cộng đồng Dev hiện nay cũng có nhiều lĩnh vực để học và phát triển hơn liên quan trực tiếp đến phần cứng và 1 trong những vị trí đang hot hiện nay là kỹ sư lập trình nhúng – Embedded Developer. Vậy thì công việc của kỹ sư lập trình nhúng là gì và tại sao nó lại hot trong hiện tại là thời gian sắp tới, bài viết này mình sẽ cùng các bạn đi tìm hiểu sâu hơn về ngành này nhé.

Hệ thống nhúng (Embedded System) là gì?

Embedded System

Trước tiên chúng ta cùng tìm hiểu về khái niệm hệ thống nhúng (Embedded System).

Embedded System là tập hợp bao gồm phần cứng và 1 phần mềm viết riêng để điều khiển, tương tác với phần cứng đó được gọi là phần mềm nhúng (Embedded Software). Đặc điểm của hệ thống nhúng là chúng có thể tự điều hành (hoạt động) với 1 mục đích cụ thể và được thiết kế để có thể tích hợp vào hệ thống lớn hơn tùy theo mục đích sử dụng.

Hiện nay các hệ thống nhúng đang có vai trò quan trọng và hữu ích trong nhiều ngành công nghiệp cũng như đời sống của chúng ta, có thể kể vài ví dụ như sau:

  • Ngành công nghiệp chế tạo máy: hầu hết các dây chuyền lắp ráp, sản xuất máy móc hiện đại ngày nay đều là những hệ thống nhúng với quy mô từ nhỏ đến lớn. Chúng có khả năng tự vận hành, thiết kế chuyên biệt để sử dụng tùy theo mục đích.
  • Ngành công nghiệp ô tô: Hộp số tự động, hệ thống phanh, cảm biến lùi, … đều là những hệ thống nhúng mà các hãng sản xuất xe trang bị và cũng được quảng cáo là những tính năng mới của họ.
  • Smarthome, Smartcity: cái này có lẽ là gần gũi nhất với anh em lập trình khi có rất nhiều dự án liên quan với mục đích tạo ra các ứng dụng điều khiển thiết bị điện, điện tử trong gia đình. Đấy cũng chính là những hệ thống nhúng, 1 phần quan trọng trong lĩnh vực IoT nói chung ngày nay.

  Một số mẹo cho việc phát triển ứng dụng hệ thống nhúng

Công việc của kỹ sư lập trình nhúng là gì?

Công việc của kỹ sư lập trình nhúng là gì?

Xưa nay anh em lập trình viên vẫn hay than vãn rằng: em chỉ là lập trình viên, em không biết sửa máy tính, máy in hay máy giặt. Tuy vậy thì câu nói này không hẳn đúng với anh em làm lập trình nhúng nhé. Mặc dù trong lĩnh vực lập trình nhúng vẫn thường chia ra mảng chuyên lập trình và mảng chuyên thiết kế phần cứng, dù vậy thì với việc phải làm trực tiếp trên thiết bị phần cứng đặc thù thì các Embedded Developer hầu như sẽ đều phải trang bị kiến thức về phần cứng. Cụ thể thì trong 1 hệ thống nhúng, chúng ta cần nắm được các thành phần cơ bản như sau:

  • ROM: Chứa chương trình, các dữ liệu được fix hoặc các constant data.
  • RAM: Chứa chương trình thực thi và các biến tạm
  • MCU: bộ xử lý tính toán trung tâm
  • Ngoài ra là các thiết bị ngoại vi khác để giao tiếp hay điều khiển phần cứng.

Xem ngay tin tuyển dụng Embedded lương cao trên TopDev

Thêm 1 khái niệm mà chúng ta cần nắm đó là firmware.

firmware là 1 chương trình hướng dẫn được ghi vào bộ nhớ của 1 thiết bị điện tử đơn với mục đích cụ thể và thực hiện các chức năng cấp thấp, ví dụ như chuyển đổi tín hiệu cảm biến. Firmware được viết bằng ngôn ngữ cấp thấp và sau đó được dịch sang mã máy để phần cứng của thiết bị có thể đọc và thực thi nó.

Như vậy, công việc của 1 kỹ sư lập trình nhúng bao gồm:

  • Viết và lập trình firmware
  • Phân tích để lựa chọn những giải pháp hợp lý nhất cho toàn hệ thống nhúng: điều này cực kỳ quan trọng liên quan đến việc tối ưu chi phí phần cứng mà vẫn đáp ứng được nhu cầu hệ thống.
  • Viết code, test, document, tài liệu liên quan cho sản phẩm của mình
  • Phối hợp với các team phát triển phần mềm khác để xây dựng các ứng dụng điều khiển cho thiết bị di động, trên các hệ điều hành, driver, …

  Áp dụng quy trình hiện đại khi làm phần mềm cho hệ thống nhúng

Cần học gì để trở thành Embedded Developer?

Như đề cập ở phần trên thì việc viết code vẫn là 1 phần quan trọng với kỹ sư lập trình nhúng, vì thế cũng giống như nghề lập trình viên nói chung, bạn cần trang bị khả năng lập trình, khả năng đọc hiểu tài liệu đa phần bằng tiếng Anh (vì hầu hết các thiết bị phần cứng sẽ được nhập về lắp ráp). Ngoài ra, 1 số kiến thức đặc thù mà bạn cần trang bị thêm trong mảng này như sau:

  • Lập trình C: C là ngôn ngữ quan trọng nhất trong lập trình nhúng, bạn cần nắm vững và thậm chí cần chuyên sâu về C.
  • Kiến thức về điện tử: các kiến thức về logic, vi điều khiển, vi xử lý, …
  • Kiến thức về hệ điều hành: kiến trúc máy tính, hệ điều hành Linux (phần lớn sẽ sử dụng hệ điều hành này), hệ điều hành thời gian thực (Realtime OS)
  • Memory (bộ nhớ): RAM, DRAM, SRAM, NOR, NAND, …
  • Cấu trúc dữ liệu và giải thuật: cái này thì thật ra lập trình nào cũng cần
  • Các loại giao tiếp: USB, SATA, PCIE, UART,…

Về kiến thức chuyên ngành, hãy bổ sung các mục dưới đây:

  • Lập trình driver thiết bị sử dụng ngôn ngữ C
  • Ngôn ngữ script: Perl, Python, Shell Script trên Linux
  • Thiết kế mạch PCB: Allegro hay Antinum
  • Thiết kế sơ đồ – Schematic Design
  • Build Environments: Makefile, Cmake
  • Ngoài ra cần học cách tương tác với phần cứng như sử dụng các công cụ đo, test board, hay thậm chí là hàn mạch sửa mạch nếu cần
  • Một số tool mà bạn có thể tham khảo trước: Cross ToolChains (Linux), Keil Embedded Tool (Windows), Putty (Windows)

Tham khảo tuyển dụng embedded Hà Nội lương cao trên TopDev

Định hướng nghề nghiệp

Như đã nhắc ở trên, có 2 hướng đi lâu dài dành cho lập trình viên nhúng.

1 là trở thành 1 lập trình viên chuyên viết phần mềm cho hệ thống nhúng (Embedded software). Công việc của bạn sẽ tập trung vào việc viết code, test, viết tài liệu cho sản phẩm mà bạn tạo ra bao gồm các driver, firmware, hệ điều hành hay các ứng dụng khác chạy trên hệ thống nhúng hoặc chạy trên các nền tảng web, mobile, PC điều khiển thiết bị.

Hướng thứ 2 thì nếu có sở thích về phần cứng nhiều hơn, hãy lựa chọn trở thành 1 người chuyên thiết kế bo mạch (board) hay còn gọi là thiết kế PCB. Hướng này đòi hỏi bạn cần trang bị kiến thức sâu về phần cứng cũng như điện tử.

Cả 2 hướng đều có tương lai phát triển rất lớn vì hiện nay nhu cầu về mảng lập trình nhúng là rất cao, ngoài ra không dễ để học và hiểu sâu được, vì thế cần có sự tìm tòi, tìm hiểu và nắm vững chuyên môn mới có thể tiến xa được trong nghề này.

Kết bài

Như vậy mình đã cùng các bạn tìm hiểu về những khái niệm cơ bản nhất trong nghề lập trình viên nhúng – Embedded Developer. Qua bài viết này hy vọng các bạn có cái nhìn tổng quát hơn về lĩnh vực lập trình này cũng như định hướng rõ ràng hơn nếu các bạn có sở thích về mảng nhúng nói riêng và IoT nói chung. Cảm ơn các bạn đã đọc bài, hẹn gặp lại các bạn trong các bài viết tiếp theo của mình.

Tác giả: Phạm Minh Khoa

Xem thêm:

Tham khảo việc làm IT lương cao tại TopDev

Năm 2022 rực rỡ tại EPAM Vietnam – Hiện thực hoá tương lai từ nguồn lực nhân sự mạnh mẽ

Vào tháng 12 vừa qua, EPAM chính thức kỉ niệm 3 năm thành lập với nhiều sự tăng trưởng mới tại thị trường Việt Nam.

EPAM là công ty cung cấp dịch vụ chuyển đổi số và phát triển phần mềm hàng đầu thế giới được thành lập từ năm 1997. EPAM tập trung vào việc xây dựng mối quan hệ lâu dài với các đối tác, hỗ trợ họ tái cơ cấu doanh nghiệp thông qua lăng kính số.

Không chỉ có thế, EPAM còn giúp khách hàng tăng trưởng nhanh hơn, agile hơn và thích ứng nhanh nhất với thị trường thông qua những dịch vụ đổi mới sáng tạo, kỹ thuật, chiến lược, thiết kế, tư vấn và đào tạo tối ưu nhất. Hiện tại EPAM đang hoạt động tại 50 nước trên thế giới với hơn 61,300 nhân viên. EPAM Vietnam được thành lập năm 2019 và đang phát triển mạnh mẽ với hơn 200 nhân viên, đem đến nhiều cơ hội việc làm cho các chuyên gia và kỹ sư phần mềm. EPAM Vietnam tập trung vào phát triển các công nghệ Java, JavaScript, Full-stack web, Mobile development, Automation testing, Data Engineering và liên tục cập nhật các công nghệ mới như Microservies, Cloud Native, Serverless và các công nghệ thế hệ tiếp theo (next-gen technologies) khác.

EPAM Vietnam

Trong năm 2022,  EPAM Vietnam chào đón gần 100 thành viên mới với hơn 16 dự án trọng điểm. Nhờ chính sách làm việc remote (từ xa), hybrid và relocation linh động, các thành viên của EPAM Vietnam hiện đang làm việc từ hơn 10 tỉnh thành và chào đón nhiều đồng nghiệp nước ngoài đến từ Ukaraine, India, Hungary, Mỹ, Nga,… Không những thế, EPAM tiếp tục phát triển mạnh mẽ hơn với việc khai trương văn phòng chính thức tại Hà Nội vào tháng 8 vừa qua.

Nhờ những nỗ lực không ngừng của đội ngũ People và Talent Acquisition nhằm tạo nên một môi trường làm việc Đa dạng và Hoà Hợp (Diversity and Inclusion), EPAM đã xuất sắc đạt vị trí thứ 2 với giải thưởng “Nơi làm việc tốt nhất Việt Nam 2022™” bởi tổ chức Great Place to Work™.

Không chỉ quan tâm đến đời sống nhân viên thông qua loạt sự kiện Family Day, Woman’s Day, Trung Thu,… EPAM còn đóng góp cho xã hội thông qua nhiều hoạt động CSR đáng chú ý. Tiêu biểu có thể kể đến chuỗi sự kiện trồng cây trong Earth Day, nâng cao ý thức về bệnh ung thư vú với Pinktober hay hợp tác, tài trợ cho nhiều tổ chức như SheCodes, AmCharm, và Passerlles numériques Việt Nam.

Việc làm IT tại HCM tại đây

EPAM Vietnam

Không dừng lại ở đó, EPAM cũng tham gia chia sẻ tại nhiều sự kiện công nghệ lớn như Vietnam Mobile Day, Vietnam Web Summit, Google Devfest và các trường Đại học trên khắp Việt Nam. Chỉ trong đầu năm 2023, EPAM tiếp tục nhận được công nhận từ toàn bộ nhân viên với 93% xác nhận đây là Great Place to Work™.

EPAM Vietnam

Để không ngừng tăng trưởng mạnh mẽ trong năm 2023, phát triển nhân lực là yếu tố quan trọng hàng đầu. Ngoài hàng trăm chương trình đào tạo nội bộ hấp dẫn, EPAM Vietnam cũng tung ra nhiều chương trình tuyển dụng hấp dẫn nhằm thu hút nguồn nhân lực chất lượng cao. Trong đó có thể kể đến chương trình Giới thiệu ứng viên External Referral Program hấp dẫn dành riêng cho các đối tượng ngoài công ty (non-employee) với cơ hội nhận $500 bonus và Iphone 14 ProMax, Apple Watch… Nếu bạn cũng đang tìm kiếm một môi trường làm việc quốc tế, chuyên nghiệp với nhiều dự án thú vị, hãy ứng tuyển ngay vào EPAM Vietnam tại: https://epa.ms/EPAM-Vietnam. EPAM luôn chào đón các bạn gia nhập và phát triển bản thân!

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

Đừng bỏ qua việc làm IT tất cả level có trên TopDev nhé!

Linux là gì? Tại sao lập trình viên nên biết cách sử dụng Linux

linux là gì

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

Chào các bạn,

Cái tên Linux chắc bạn nghe nhiều rồi nhỉ, và có thể bạn đã biết Linux là tên một hệ điều hành máy tính được các lập trình viên yêu thích, thế nhưng bạn mới chỉ nghe vậy thôi, chứ tại sao các lập trình viên lại yêu thích hệ điều hành này thì bạn chưa biết, có phải vậy không? Nếu đúng thì … bạn thật giống mình ngày trước. Trước kia, khi nghe các “developer nhà người ta” khuyên rằng “là lập trình viên thì nên biết cách dùng Linux” mình cũng rất tò mò, không hiểu Linux là gì? cái OS này có gì hay ho mà lại được họ ca ngợi như vậy. Mình cũng có bỏ công tìm hiểu, thì chỉ thấy họ nói: Linux nhẹ, Linux linh hoạt, Linux miễn phí,… nhưng từng đó lý do là chưa đủ để mình cảm thấy “thích” hệ điều hành này, phải mãi cho tới khi…

Cho tới khi đi làm, vì công việc mà bắt buộc phải sử dụng tới Linux để phát triển dự án, mình mới hiểu được lý do tại sao các developer tiền bối lại khuyên vậy. Cụ thể lý các do là gì, mình xin được chia sẻ lại qua bài viết ngắn gọn này.

I. LINUX VÀ CÁC BẢN PHÂN PHỐI CỦA LINUX

1.1 Linux là gì?

Dẫu ai cũng biết rằng nó là cái gì đó rồi. Nhưng mình vẫn muốn nhắc lại chút để chúng ta có chung khái niệm về Linux mà mình đề cập ở dưới.

Ngày nay, Linux được biết đến là tên một hệ điều hành máy tính (để dễ hiểu thì bạn cứ tưởng tượng nó là cái gì đó tương tự như Windows, MacOS vậy). Nhưng nói một cách chính xác thì Linux chỉ là kernel (hạt nhân) của hệ điều hành.

Còn hệ điều hành Linux mà ngày nay mọi người vẫn nhắc đến thì có tên đầy đủ là GNU/Linux – chắc do cái tên GNU/Linux dài quá nên người ta mới gọi tắt là Linux cho ngắn gọn.

  Linux - Setup môi trường cho Web Developer

Giới thiệu thêm về GNU/Linux

GNU là một dự án được ra đời vào năm 1983 bởi Richard Stallman. Dự án này hướng đến một hệ điều hành miễn phí, nơi mà mọi người có thể tự do chỉnh sửa, phát triển, sao chép theo ý mình.

Bản thân dự án GNU sau khi ra đời đã đạt được nhiều thành tự lớn, đóng góp nhiều sản phẩm hữu ích cho cộng đồng. Nhưng GNU vẫn còn thiếu một thành phần vô cùng quan trọng để trở thành một hệ điều hành hoàn chỉnh, đó chính là kernel – thành phần tương tác với phần cứng máy tính.

Trong dự án GNU, một kernel có tên GNU Hurd cũng được nhắc đến, nhưng do chưa sẵn sàng ra mắt nên các kernel phi GNU cũng có thể sử dụng được với GNU – mà nổi bật nhất chính là Linux kernel. Kể từ đó cái tên GNU/Linux đã ra đời và được biết đến là hệ điều hành phát triển bằng cách kết hợp giữa GNU với Linux kernel.

Để phù hợp với nhiều tài liệu khác, cũng như cách mà mọi người vẫn hiểu Linux là gì, thì khái niệm Linux mà mình nhắc tới trong bài viết này là chỉ hệ điều hành GNU/Linux hoặc các bản phân phối của Linux, chứ không phải là Linux kernel. Bạn hãy chú ý.

Tham khảo việc làm Linux Hồ Chí Minh hấp dẫn trên TopDev

1.2 Các bản phân phối của Linux

Bản phân phối của Linux (Linux distribution hay Linux distro) là chỉ những hệ điều hành được phát triển dựa trên hệ điều hành Linux. Một bản phân phối của Linux thường sẽ được tích hợp sẵn một số phần mềm tiện ích, một trình quản lý gói (packages manager), một window system (phần lớn sử dụng X Window System), window manger và một môi trường desktop.

Lưu ý: X Window System và window manager không liên quan gì tới hệ điều hành Windows của Microsoft.

Một số bản phân phối điển hình của Linux đang phổ biến hiện nay (2020) có thể kể đến như: Ubuntu, CentOS, Fedora – chắc bạn cũng từng nghe qua những cái tên đó rồi chứ nhỉ.

  5 lý do lập trình viên nên sử dụng hệ điều hành Linux

II. TẠI SAO LẬP TRÌNH VIÊN NÊN BIẾT CÁCH SỬ DỤNG LINUX?

Mình nhấn mạnh từ “nên”, nghĩa là không bắt buộc, nghĩa là bạn vẫn có thể trở thành lập trình viên mà không cần phải biết cách dùng Linux. Nhưng nếu bạn muốn trở thành một lập trình viên “hợp thời”, muốn khám phá những giải pháp công nghệ hiện đại, muốn trở thành “hổ thêm cánh” thì chắc chắn phải biết cách dùng Linux. Và dưới đây là một số lý do điển hình:

2.1 Các server phần lớn đều sử dụng hệ điều hành Linux

Mặc dù rất khó để tìm thấy một chiếc laptop của người dùng thông thường lại được cài hệ điều hành Linux. Nhưng đối với các server thì lại khác, Linux là hệ điều hành phổ biến nhất trên các server bởi những lý do sau:

  • Miễn phí: Bạn sẽ không phải tốn chi phí bản quyền khi sử dụng hệ điều hành Linux.
  • Ít tốn tài nguyên phần cứng: Linux được cho là ít tốn tài nguyên phần cứng hơn là hệ điều hành Windows, hay cũng có thể nói Linux có thể chạy tốt trên các phần cứng thông thường (phần cứng rẻ).
  • Bảo mật và cập nhật nhanh chóng: Vì linux là mã nguồn mở, nên khi phát hiện lỗi, sẽ nhận được sự đóng góp nhiệt tình từ cộng đồng người sử dụng trên khắp thế giới.

Từ những lý do trên, có thể thấy rằng Linux là hệ điều hành “tối ưu cho túi tiền”. Bạn có thể tập trung chi phí cho phần cứng của server thay vì phải mất một khoản để trả cho bản quyền của hệ điều hành.

Mặt khác, các lập trình viên lại là đối tượng thường xuyên tọc mạch vào các server để nghịch ngợm. Vì vậy, bạn nên biết sử dụng Linux để có thể làm chủ server của mình.

Nếu bạn chưa bao giờ làm việc với server Linux, thì có nghĩa là chưa tới lúc bạn động đến chúng, chứ không có nghĩa là bạn không cần chúng.

Blog phambinh.net cũng được cài đặt trên VPS Linux.

2.2 Là môi trường lý tưởng cho các công nghệ Open Source

Bản thân Linux là một open source, nên nó rất dễ dàng kết hợp với các công nghệ open source khác. Ngoài ra, các công nghệ open source phần lớn đều tương thích với hệ điều hành Linux (thật ra mình chưa gặp một open source nào mà không hỗ trợ Linux cả).

Mặt khác, phát triển sản phẩm open source lại đang là xu hướng. Bằng chứng là ngay cả ông lớn Microsoft – nổi tiếng với cách làm closed source cũng đã có sản phẩm open source cho riêng mình là VsCode – một editor được nhiều lập trình viên yêu thích. Hay trong mấy năm gần đây, Microsoft cũng đã mua lại github và npm, vốn là 2 nền tảng liên quan nhiều tới các open source. Bạn cũng có thể thêm các open source của Microsoft tại đây: https://opensource.microsoft.com

Việc cài đặt thêm các nền tảng open source khác trên Linux thật sự dễ dàng thông qua các trình quản lý gói. Ví dụ để cài đặt PHP trên Ubuntu (một distro của Linux) bạn chỉ cần chạy lệnh sau trên CLI:

sudo apt install php

Nếu như bạn là một web developer (PHP, NodeJS), android developer thì môi trường phát triển tốt nhất có lẽ là Linux.

2.3 Có ứng dụng CLI mạnh mẽ

Mình đã phân vân không biết có nên đưa mục này vào không. Vì trên các bản distro của Linux thường sẽ có sẵn một app CLI là Terminal, và điều khiến mình cho rằng CLI trên Linux mạnh mẽ hơn các hệ điều hành khác, cụ thể là với Windows là do cái app Terminal này dễ dàng sử dụng hơn so với Command Prompt hay Powershell có sẵn trên Windows. Nhưng mình cũng gặp rất nhiều bạn chuyển qua dùng Linux đơn giản chỉ vì cái cái Terminal của Linux dùng được tổ hợp phím control + C / control + V để copy và paste, thay vì phải sử dụng chuột hoặc một tổ hợp phím “lạ lùng” nào đó để thực hiện công việc tương tự trên Windows.

Sau khi suy nghĩ, mình quyết định đưa mục này vào bài viết.

III. MỘT SỐ LƯU Ý VỀ LINUX

Phía trên toàn là thấy khen Linux không à, sợ các bạn sẽ gỡ Windows để mà cài đặt Linux nên mình viết thêm mục này để lưu một số điều về Linux.

3.1 Nếu bạn chuyên làm các stack liên quan tới Windows, biết Linux có thể không giúp ích cho bạn

Nếu bạn chỉ làm C#, aps.net, Visual basic, hay bất kỳ công nghệ độc quyền nào của Microsoft thì biết linux sẽ không giúp ích gì cho bạn. Bởi bản thân ông lớn Microsoft đã trang bị sẵn một hệ sinh thái khép kín cho các công nghệ của mình.

3.2 Linux không phù hợp với các ứng dụng văn phòng hay thiết kế

Linux tuy rất phù hợp để lập trình, để phát triển các sản phẩm trên nền tảng open source, nhưng lại không hỗ trợ tốt các ứng dụng văn phòng như MS world, Excel, Power Point,… Mặc dù trên Linux có hai bộ ứng dụng là LibreOffice và OpenOffice để giải quyết vấn đề này, nhưng nó vẫn không mượt mà và ổn định như MS Office có trên Windows được. Cũng đúng thôi, MS Office là một trong những niềm tự hào của Microsoft mà, đâu dễ dàng thay thế được.

Tuy lập trình viên ít khi phải động tới các ứng dụng dạng này, nhưng không phải là không có.

Một phần mềm nữa là Photoshop cũng không có bản hỗ trợ trên Linux, với những bạn có nhu cầu cắt giao diện từ Photoshop thì đây cũng là vấn đề đang lưu ý đó.

Về cách khắc phục, thao tác với các ứng dụng văn phòng bạn có thể sử dụng LibreOffice, OpenOffice, hoặc Google docs, Google sheet, Google slide để thay thế. Với việc cài photoshop, bạn có thể cài trên máy ảo windows để sử dụng, hoặc chọn một nền tảng khác photoshop để sử dụng.

Lưu ý: Cách khắc phục trên chỉ giải quyết được phần nào, chứ không giải quyết được triệt để vấn đề. Cách giải quyết triệt để là không dùng Linux nữa.

3.4 Sao chỉ thấy so sánh Linux với Windows vậy, sao không thấy so sánh với MacOS?

Có một câu chuyện dài phía sau câu hỏi này.

Có thể bạn đã biết, MacOS được phá triển dựa trên BSD – một hệ điều hành thuộc họ nhà UNIX. Còn Linux thì chính là GNU (như mình nói ở phần đầu), trong khi đó GNU là một hệ điều hành clone (nhân bản, học tập ý tưởng, bắt chước) UNIX. Do đó, tuy GNU không được phát triển dựa trên UNIX và không được coi là hệ điều hành thuộc họ nhà UNIX, nhưng lại có khá nhiều điểm tương đồng với các hệ điều hành thuộc họ nhà UNIX, cụ thể là MacOS. Vì vậy có thể coi MacOS và Linux là hai anh em tuy không cùng bố mẹ, nhưng lại khá giống nhau. Mà giống nhau, thì người ta không cần phải so sánh.

Ngoài ra, MacOS là độc quyền của Apple, trong khi đó Apple lại chưa có dịch vụ nào liên quan tới cloud server giống như Windows cả – một trong những điều khiến người ta phải so sánh với Linux nhất.

IV. CÀI ĐẶT UBUNTU ĐỂ NGHỊCH

Sau cùng, nếu bạn muốn trải nghiệm Linux, thì dưới đây là vài gợi ý của mình để bạn có thể cài đặt và trải nghiệm Ubuntu – distro nổi bật nhất của Linux:

  • Mua một máy tính mới và cài đặt Ubuntu làm hệ điều hành: Cách này giành cho những bạn có tiền, chịu đầu tư để học hỏi :D.
  • Cài Ubuntu song song với hệ điều hành chính: Dành cho những bạn muốn có trải nghiệm mượt mà với Ubuntu nhưng lại không muốn mua máy tính mới.
  • Cài máy ảo Ubuntu: Dành cho những bạn muốn trải nghiệm nhanh hệ điều hành này.

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

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

Xem thêm các việc làm lĩnh vực IT hấp dẫn trên TopDev

CLI là gì? Tại sao developer nên làm quen với CLI

CLI là gì?

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

Chào các bạn,

Command line interface (CLI) là một loại giao diện khá quen thuộc đối với các anh em developer. Tuy nhiên lúc mới bắt đầu học lập trình, mình không thích sử dụng các tool trên CLI vì cảm thấy chúng khó sử dụng, khó tiếp cận hơn các tool sử dụng GUI. Nhưng càng về sau, do các tool sử dụng GUI không đáp ứng được nhu cầu công việc, buộc mình phải sử dụng tới CLI thì mình mới nhận ra rằng CLI có rất nhiều cái hay, cái lợi mà GUI không có.

Hơn nữa, mình nhận ra rằng developer thì nên biết cách sử dụng CLI hơn là không, tại sao lại như vậy thì các bạn hãy theo dõi bài viết này của mình nhé.

I. GUI VÀ CLI

Mình giới thiệu qua một chút về CLI và GUI cho bạn nào chưa biết nhé.

GUI – Graphical User Interface: Là giao diện sử dụng ở dạng đồ họa, đây là loại giao diện phổ biến và gần gũi với hầu hết người dùng.

Giao diện này mình dám chắc 100% ai cũng từng nhìn thấy và sử dụng rồi, có điều là mọi người có biết là mình vừa sử dụng nó hay không thôi. Hình dung đơn giản, thì tất cả các phần mềm mà trên giao diện xuất hiện các nút bấm, các menu, hình ảnh,… có cách sử dụng trực quan thì đều là GUI (bạn sẽ hiểu rõ thế nào là GUI hơn sau khi hiểu về CLI).

CLI – Command Line Interface: Là giao diện dòng lệnh, đây là loại giao diện mà không phải ai cũng biết, cũng như không phải ai cũng biết cách sử dụng.

Command-Line-Interface

Đặc điểm chung của các phần mềm CLI là đều có cách sử dụng không mấy dễ chịu đối với người mới bắt đầu, do có cách sử dụng không trực quan như GUI, không có nút bấm, không có các menu chỉ dẫn. Cách duy nhất để bạn tương tác với CLI là sử dụng dòng lệnh.

Ví dụ để tạo ra một thư mục mới trên máy tính với GUI. Bạn sẽ “Nhấp chuột phải > New > New folder”, còn đối với CLI thì bạn phải gõ lệnh “mkdir ten-thu-muc”.

Vấn đề lớn nhất của các bạn mới sử dụng CLI là do giao diện “xấu” nên nhìn không quen mắt, cách sử dụng khó do không biết hoặc không nhớ lệnh để thực hiện đúng yêu cầu.

  Tự tạo một chương trình CLI trong quản lý công việc

II. TẠI SAO LẠI CẦN CÓ CLI?

Mặc dù được cho là khó sử dụng hơn so với GUI, thế nhưng CLI vẫn có đất dụng võ, lý do là vì:

Không phải phần mềm nào cũng có GUI để sử dụng: Một phần mềm GUI sẽ tốn công sức và thời gian để lập trình ra hơn là CLI. Nên các nhà phát triển sẽ cân nhắc việc sử dụng CLI nếu GUI không cần thiết. Ví dụ như các phần mềm chạy ẩn trên máy tính chẳng hạn, có GUI hay không không quá quan trọng.

Không phải hệ điều hành nào cũng hỗ trợ GUI: Các hệ điều hành quen thuộc với chúng ta như là windows, android, ios, macOs đều hỗ trợ GUI nhưng bên cạnh đó có những hệ điều hành không hỗ trợ GUI như MS-DOS hoặc lược bỏ đi phần GUI như Linux cài trên các máy chủ ảo (VPS). Trong trường hợp không hỗ trợ GUI hoặc lược bỏ GUI như vậy thì chỉ còn một cách duy nhất để tương tác với máy tính là sử dụng CLI.

CLI đơn giản hơn GUI: GUI tuy dễ hiểu, dễ tiếp cận nhưng lại rườm rà, cần nhiều bước để thực hiện. Ví dụ để xem địa chỉ IP của máy tính, bạn sẽ phải thực hiện một vài thao tác như vào “Control panel > New working > bla bla gì đó mà mình cũng không nhớ”, nhưng nếu sử dụng CLI thì bạn chỉ cần gõ lệnh ifconfig (hoặc ipconfig tùy hệ điều hành) là có thể xem được ngay. Không chỉ có thao tác xem địa chỉ IP, mà còn có nhiều thao tác nữa cho thấy rằng CLI tiện lợi hơn GUI.

Tham khảo việc làm Linux mới nhất trên TopDev

III. TẠI SAO DEVELOPER NÊN LÀM QUEN VỚI CLI?

3.1 Tiết kiệm được nhiều thời gian thao tác nếu thành thạo

CLI tuy khó tiếp cận lúc ban đầu, nhưng khi quen tay thì mọi thứ lại trở nên đơn giản. Chưa kể nếu sử dụng thành thạo CLI, bạn có thể không cần dùng tới chuột do các thao tác di chuyển con trỏ, thay đổi cửa sổ làm việc hoàn toàn có thể thực hiện từ bàn phím. Tay phải của bạn sẽ không phải chuyển qua chuyển lại giữa bàn phím – chuột rồi lại chuột – bàn phím nữa, vừa nhìn chuyên nghiệp hơn mà lại tiết kiệm được kha khá thời gian trong công việc.

  Xác định đối tượng giao diện UI trong ứng dụng Android

3.2 Đa số các tool cho developer đều là CLI

Đúng vậy đó, các tool cho developer đa phần đều là CLI. Ví dụ điển hình như là npm, yarn, composer, docker, git,… đều được ưu tiên sử dụng trên CLI hơn là trên GUI. Nguyên nhân là do các developer thì đều yêu thích sự đơn giản, nhanh chóng và linh hoạt. Để đáp ứng được các yêu cầu đó thì CLI là sự lựa chọn tốt hơn GUI. Nếu như bạn phản đối quan điểm này thì sẽ có cực kỳ ít tool cho bạn sử dụng, nên cách tốt nhất là nên học cách làm quen với CLI.

3.3 Có thể sẽ phải làm việc nhiều với các server Linux

Đa phần các server đều sử dụng các bản phân phối của Linux làm hệ điều hành và thường bị lược bỏ đi phần GUI. Vậy chỉ còn cách sử dụng CLI để giao tiếp với các server này. Mặt khác, đã là developer thì ít nhiều gì cũng có lúc bạn động đến việc cấu hình, cài cắm thêm các gói, các module cần thiết cho server chạy Linux, nên bạn sẽ không thể tránh khỏi việc phải sử dụng tới CLI.

IV. KẾT LUẬN

Qua bài viết này, mình muốn đem tới cho các bạn những ưu điểm của CLI so với GUI, và lý do tại sao developer nên làm quen với CLI, tóm tắt lại có một vài ý quan trọng như sau

  • Không phải chỗ nào cũng có GUI cho bạn sử dụng
  • Các tool cho developer thì đa phần đều là CLI
  • Vận dụng CLI thành thạo sẽ tiết kiệm thời gian hơn là GUI

Bài viết được viết dựa trên kinh nghiệm cá nhân, xin nhận mọi gạch đá.

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

Xem thêm:

Chuyện gõ tiếng Việt trên Linux

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

Top 10 câu hỏi phỏng vấn JavaScript cực chi tiết

Top 10 câu hỏi phỏng vấn JavaScript

Theo khảo sát dành cho các lập trình viên hàng năm của Stack Overflow (Stack Overflow Developer Survey) thì trong 2 năm trở lại đây, JavaScriptngôn ngữ lập trình phổ biến nhất hiện nay. Mức phổ biến của JavaScript (JS) khiến cho nhu cầu tuyển dụng lập trình viên về ngôn ngữ này trở nên rất lớn trong những năm trở lại đây. Nếu bạn cũng đang có dự định chuẩn bị cho việc cuộc phỏng vấn tuyển dụng vị trí lập trình viên JS, bài viết này sẽ dành cho bạn. Chúng ta cùng nhau đi qua top 10 những câu hỏi phỏng vấn về JavaScript phổ biến nhất nhé.

Câu 1: JavaScript là gì? Nó thường sử dụng để làm gì?

Đây là câu hỏi cơ bản mà thường để bắt đầu phỏng vấn chuyên môn thì nhà tuyển dụng sẽ hay hỏi. Tất nhiên nếu bạn apply vào vị trí Senior thì sẽ không nhà tuyển dụng nào hỏi câu này đâu, mặc dù vậy hãy nên chuẩn bị kiến thức chuẩn chỉnh 1 chút để trả lời câu này nhé.

JavaScript là 1 ngôn ngữ lập trình thông dịch dựa trên nguyên mẫu (prototype-based) với cú pháp phát triển từ C. JS được phát triển bởi Netscape từ tháng 5 năm 1995, đến hiện nay nó đã được sử dụng rộng rãi cho các trang web ở cả phía người dùng (client) và phía máy chủ (server) sử dụng NodeJS.

Ban đầu, JS được tạo ra để giúp các trang web có thể tương tác 1 cách linh hoạt hơn với người dùng; sau này với sự phát triển của nó, các nhà phát triển JS đã tạo ra nhiều thư viện, framework khác nhau giúp JS có thể chạy bên ngoài trình duyệt, đồng thời có thể hoạt động được ở cả client và server.

  9 Câu Hỏi Phỏng Vấn Frontend Developer Có Thể Bạn Chưa Biết

  Những câu hỏi phỏng vấn React thường gặp

Câu 2: ECMAScript là gì? 

ECMAScript là 1 chuẩn hóa của các ngôn ngữ client-side cho Jscript, JavaScript, ActionScript.

Trước đây khi các ngôn ngữ kịch bản được ra đời thì nó chỉ được hỗ trợ riêng cho các trình duyệt nhất định, ví dụ như JavaScript cho trình duyệt Netscape Navigator, Jscript hỗ trợ Internet Explorer, … Để các web có thể chạy được cùng lúc trên nhiều trình duyệt khác nhau thì ECMAScript ra đời như 1 tiêu chuẩn giải quyết vấn đề trên.

Phiên bản ECMA thứ 6 (ES6) hay ECMA2015 ra mắt năm 2015 bổ sung thêm các cú pháp mới quan trọng liên quan đến class, module hay function; đây là phiên bản được sử dụng rộng rãi hiện nay (hoặc các bản update sau) trong các dự án.

Tham khảo việc làm JavaScript tại Hồ Chí Minh trên TopDev

Câu 3: Những tính năng mới trong ES6

Có tương đối nhiều update về tính năng trong phiên bản ES6, bạn có thể nêu càng nhiều càng tốt; tuy vậy hãy cố gắng nắm được 1 vài điểm sau:

  • Arrow Function: cú pháp viết function sử dụng mũi tên (arrow) giúp viết code gọn và clear hơn
  • Default Parameters: sử dụng phép gán giá trị mặc định ngay ở vị trí khai báo tham số cho function
  • Rest Parameters: giúp truyền tham số vào 1 hàm mà không cần khai báo clear từ đầu hay bị giới hạn số lượng tham số
  • Let và Var: khai báo biến sử dụng let để xác định phạm vi hoạt động trong 1 khối
  • Template Literals: hiển thị chuỗi string chứa biến sử dụng cặp dấu “ (backtick)
  • Promise: xử lý các vấn đề bất đồng bộ (lưu ý là async/await mới được bổ sung từ ES7 nhé)

Câu 4: Các kiểu dữ liệu trong JavaScript

Trong JS, có 6 kiểu dữ liệu nguyên thủy (primitive data type) bao gồm: undefined, boolean, number, string, bigint và symbol. Kiểu dữ liệu còn lại được gọi là kiểu dữ liệu tham chiếu (reference data types), bao gồm object, array và function (lưu ý là trong JS thì mọi thứ được đều thuộc loại object). 

Điểm khác nhau cơ bản giữa 2 kiểu dữ liệu này là cách lưu trữ dữ liệu lên bộ nhớ: với dữ liệu nguyên thủy, giá trị thực của biến sẽ được lưu trữ trực tiếp; ngược lại với kiểu dữ liệu tham chiếu thì các object sẽ chứa các địa chỉ bộ nhớ (tham chiếu) đến 1 vị trí khác trong bộ nhớ.

Câu 5: “this” trong JS là gì?

“this” trong JS được dùng để đại diện cho 1 object – Object ở đây là đại diện cho chủ thể của ngữ cảnh và nó phụ thuộc vào lúc runtime chứ không phải lúc khởi tạo. Hiểu đơn giản hơn thì “this” đóng vai trò là 1 con trỏ, trỏ đến chính object gọi hàm đó.

Về bản chất thì 1 function bất kỳ đều có property giống như object; khi chúng ta thực thi 1 function, nó sẽ có property “this” chứa item của object đang gọi đến function đó.

Câu 6: Promise trong JS là gì?

Promise là 1 đối tượng được sử dụng cho tính toán bất đồng bộ, nó đại diện cho 1 tiến trình hay 1 tác vụ chưa thể hoàn thành ngay được. Trong tương lai, 1 Promise sẽ trả về giá trị hoặc là được giải quyết (resolve) hoặc là bị từ chối (reject). Promise ra đời nhằm giải quyết vấn đề callback hell trong các tác vụ cần chờ kết quả từ 1 hành động chưa xác định ngay được kết quả như call API lên server.

Với ES7 trở đi, chúng ta có thể sử dụng async/await để tạo 1 Promise ngắn gọn và clear hơn.

Câu 7: Những method để truy cập đến phần tử HTML trong JS

 Có 1 số method cho việc truy cập đến các phần tử trên DOM như sau:

  • getElementById(): lấy 1 element thông qua id
  • getElementByClass(): lấy 1 element thông qua class
  • getElementsByTagName(): lấy 1 element bằng tên của tag name
  • querySelector(): function css style selector và sẽ trả về giá trị đầu tiên

Câu 8: Sự khác nhau giữa forEach và map

.forEach là vòng lặp dựa vào các phần tử có trong mảng, nó sẽ thực hiện callback trong mỗi vòng lặp và không trả về giá trị.

.map cũng xử lý vòng lặp dựa vào các phần tử có trong mảng, tuy vậy khác với forEach thì nó sẽ trả về giá trị để tạo ra 1 mảng với dựa trên các giá trị trong vòng lặp.

  12 Thư viện JavaScript trực quan hoá dữ liệu hot nhất năm 2024

Câu 9: Kể tên 1 số pattern thường dùng trong lập trình JS

Design pattern là các phương pháp để giải quyết vấn đề thường gặp mà có thể tái sử dụng được. Với JS, có 1 vài pattern nổi tiếng như:

  • Module Pattern: 1 kiểu đóng gói code trong JS hay giả lập tính chất đóng gói của hướng đối tượng
  • Revealing Module Pattern: 1 phiên bản nâng cấp của Module Pattern với việc tạo ra các public function để gọi tới các private function và variables
  • Singleton Pattern: tạo ra những object chỉ khởi tạo 1 lần duy nhất giúp tối ưu bộ nhớ
  • Factory Pattern: tạo ra các object mà không cần chỉ định rõ chính xác class hay constructor nào
  • Decorator Pattern: sử dụng để mở rộng chức năng của 1 object mà không làm thay đổi class hay hàm hiện tại.

Câu 10: Kể tên 1 số framework, thư viện hay dùng của JS

1 số thư viện và framework về UI phổ biến hiện nay:

1 số thư viện hữu ích:

  • Moment.js: thư viện xử lý datetime
  • Lodash: cung cấp các hàm tiện ích cho các tác vụ lập trình bằng cách sử dụng mô hình lập trình hàm
  • Chart.js: trực quan hóa dữ liệu, dựng biểu đồ

Trên đây là danh sách 10 câu hỏi phổ biến khi phỏng vấn tuyển dụng vị trí JavaScript mà mình tổng hợp được. Còn rất nhiều câu hỏi khác liên quan đến kiến thức chuyên môn cũng như kinh nghiệm làm việc của bạn. Vì vậy hãy cố gắng nắm vững kiến thức cơ bản về JS và điều đó sẽ giúp bạn tự tin hơn trong cuộc phỏng vấn sắp tới. Hy vọng bài viết hữu ích dành cho bạn, và hẹn gặp lại trong các bài viết tiếp theo của mình.

Tác giả: Phạm Minh Khoa

Xem thêm:

Tìm việc làm IT mới nhất trên TopDev

Giới thiệu Java Service Provider Interface (SPI) – Tạo các ứng dụng Java dễ mở rộng

Java Service Provider Interface

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

Hầu hết vòng đời của một ứng dụng xoay quanh việc bảo trì. Một ứng dụng có thể mở rộng cho phép bảo trì dễ dàng, tức là nâng cấp một tính năng mà không ảnh hưởng đến toàn bộ ứng dụng. Trong bài viết này chúng ta sẽ tìm hiểu về Java Service Provider Interface (SPI) và cách chúng ta có thể áp dụng nó vào trường hợp sử dụng thực tế để tạo các ứng dụng dễ dàng mở rộng, tạo ứng dụng theo các kiến trúc module, plugin.

Các thành phần của Java Service Provider Interface (SPI)

Một Service Provider framework là một hệ thống trong đó nhiều nhà cung cấp dịch vụ (Service Provider) implement một Service và hệ thống này cung cấp các implement cho client sử dụng. SPI giúp giảm kết dính và che dấu thông tin giữa các thành phần của ứng dụng.

Java SPI định nghĩa các thành phần chính sau:

  • Service : là một tập hợp các interface/ abstract class mà nó cung cấp quyền truy cập vào một số chức năng hoặc tính năng ứng dụng cụ thể.
  • Service Provider Interface (SPI): là một tập hợp interface/ abstract hoạt động như một proxy hoặc điểm cuối (endpoint) cho service.
  • Service Provider : là một triển khai cụ thể của SPI. Nó chứa một hoặc nhiều class cụ thể implements hoặc extends một Service.
  • ServiceLoader : là thành phần không thể thiếu của SPI. Nó có vai trò tìm kiếm và load các implements khi được yêu cầu. Nó sử dụng context classpath để xác định vị trí các provider implement provider và lưu chúng vào cache để tăng performance.

  Bridge Pattern trong Java – Code ví dụ Composite Pattern

  Top 5 tips and tricks hot nhất của JavaScript năm 2024

Cài đặt và sử dụng SPI

Giả sử chúng ta có một ứng dụng cung cấp các service cho các ứng dụng khác sử dụng. Mỗi service của chúng ta có nhiều provider (implementation) khác nhau. Các ứng dụng có thể lựa chọn provider mà nó cần hoặc tự implement một provider khác tuân theo đặc tả của SPI.

Cài đặt và sử dụng SPI

Để dễ dàng thêm bớt service mà không ảnh hưởng đến các ứng dụng khác, chúng ta sẽ sử dụng tính năng có sẵn trong Java 6 là ServiceLoader. Hãy xem ví dụ sau:

Đầu tiên, tạo project maven với tên là JavaSPI. Cấu hình file pom.xml như sau:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.gpcoder</groupId>
    <artifactId>JavaSPI</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>JavaSPI</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
    </dependencies>
</project>

Tiếp theo tạo một Service, chẳng hạn chúng ta cung cấp Serivce hỗ trợ tìm kiếm. Service này chỉ gồm 1 phương thức đơn giản search().

Tham khảo việc làm Java mới nhất trên TopDev

SearchService.java

package com.gpcoder.spi;

import java.util.List;

public interface SearchService {

    List<Result> search(String text);
}

Tiếp theo, chúng ta sẽ tạo các Provider được cung cấp bởi hệ thống:

  • DefaultSearchService : hỗ trợ search thông thường.
  • FullTextSearchService : hỗ trợ search toàn văn.

DefaultSearchService.java

package com.gpcoder.spi;

import java.util.List;

public class DefaultSearchService implements SearchService {

    @Override
    public List<Result> search(String text) {
        System.out.println("DefaultSearchService#search()");
        return null;
    }
}

FullTextSearchService.java

package com.gpcoder.spi;

import java.util.List;

public class FullTextSearchService implements SearchService {

    @Override
    public List<Result> search(String text) {
        System.out.println("FullTextSearchService#search()");
        return null;
    }
}

Để sử dụng SPI, chúng ta cần tạo một file cấu hình:

  • Tên file: là tên đầy đủ của Service, bao gồm cả tên package. Ví dụ: com.gpcoder.spi.SearchService
  • Nội dung file: là tên đầy đủ của Service implement, mỗi implement trên một dòng. Ví dụ: com.gpcoder.spi.DefaultSearchService
    com.gpcoder.spi.FullTextSearchService
  • Vị trí: đặt file này trong thư mục resources/META-INF/services

Cuối cùng, chúng ta sẽ sử dụng ServiceLoader để lấy các Provider đã được đăng ký thông qua cấu hình SPI ở trên:

package com.gpcoder.spi;

import java.util.ServiceLoader;

public class ServiceLoaderExample {
    public static void main(String[] args) {
        System.out.println("App started ");

        ServiceLoader<SearchService> serviceLoader = ServiceLoader.load(SearchService.class);
        for (SearchService provider : serviceLoader) {
            provider.search("");
        }

        System.out.println("App finished ");
    }
}

Output của chương trình:

App started 
DefaultSearchService#search()
FullTextSearchService#search()
App finished

Đặt trường hợp bây giờ chúng ta có một project khác, cần sử dụng các Service được cung cấp bởi project trên. Tiếp tục, chúng ta tạo một project maven khác tên là JavaSPIChild1 và cấu hình lại file pom.xml như sau:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.gpcoder.child1</groupId>
    <artifactId>JavaSPIChild1</artifactId>
    <packaging>jar</packaging>

    <name>JavaSPIChild1</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <parent>
        <groupId>com.gpcoder</groupId>
        <artifactId>JavaSPI</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../JavaSPI</relativePath>
    </parent>

    <dependencies>
         <dependency>
             <groupId>com.gpcoder</groupId>
             <artifactId>JavaSPI</artifactId>
             <version>0.0.1-SNAPSHOT</version>
         </dependency>
     </dependencies>
</project>

Tiếp theo chỉnh sửa lại một chút file pom.xml của project JavaSPI, thay đổi packing từ jar thành pom.

<packaging>pom</packaging>

Chi tiết về cách tạo và cấu hình project maven với nhiều module các bạn vui lòng xem lại bài viết: Xây dựng dự án nhiều Module với Maven.

Giả sử trong ứng dụng con này chúng ta cần sử dụng một Provider khác. Chúng ta có thể thực hiện bằng cách tạo một class mới implements từ SearchService.

package com.gpcoder.child1;

import java.util.List;

import com.gpcoder.spi.Result;
import com.gpcoder.spi.SearchService;

public class Child1SearchService implements SearchService {

    @Override
    public List<Result> search(String text) {
        System.out.println("Child1SearchService#search()");
        return null;
    }
}

Để sử dụng SPI, chúng ta cần tạo một file cấu hình com.gpcoder.spi.SearchService trong thư mục resources/META-INF/services như sau:

com.gpcoder.spi.DefaultSearchService
com.gpcoder.child1.Child1SearchService

Lưu ý: chỉ khai báo các Service mà project JavaSPIChild1 cần sử dụng. Trong ví dụ này, chúng ta chỉ sử dụng DefaultSearchService và Child1SearchService.

Bây giờ, chúng ta sẽ sử dụng ServiceLoader để lấy các Provider đã được đăng ký thông qua cấu hình SPI ở trên:

package com.gpcoder.child1;

import java.util.ServiceLoader;

import com.gpcoder.spi.SearchService;

public class Child1ServiceLoaderExample {
    public static void main(String[] args) {
        System.out.println("App started ");

        ServiceLoader<SearchService> providers = ServiceLoader.load(SearchService.class);
        for (SearchService provider : providers) {
            provider.search("");
        }

        System.out.println("Child1SearchService: ");
        SearchService service = getServiceByName(Child1SearchService.class.getCanonicalName());
        service.search("");

        System.out.println("App finished ");
    }

    public static SearchService getServiceByName(String className) {
        ServiceLoader<SearchService> providers = ServiceLoader.load(SearchService.class);
        for (SearchService provider : providers) {
            if (provider.getClass().getCanonicalName().equals(className)) {
                return provider;
            }
        }
        return null;
    }
}

Output của chương trình:

App started
DefaultSearchService#search()
Child1SearchService#search()
Child1SearchService:
Child1SearchService#search()
App finished

Như bạn thấy, ứng dụng của chúng ta rất dễ dàng thêm/ bớt module mà không cần phải thay đổi hay chỉnh sửa code ở project cha.

Toàn bộ cấu trúc thư mục của project như sau:

  cấu trúc thư mục của projectcấu trúc thư mục của project

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

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

Xem thêm công việc CNTT hấp dẫn trên TopDev

Giới thiệu về JSON Binding trong Jakarta EE

JSON Binding trong Jakarta EE

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

JSON Binding là một specification của Jakarta EE về convert qua lại giữa JSON data và Java object, tương tự như thư viện Jackson mà mình đã giới thiệu với các bạn. Trong bài viết này, chúng ta sẽ cùng nhau tìm hiểu về JSON Binding và cách sử dụng nó với một implementation của nó là Eclipse Yasson các bạn nhé!

Đầu tiên, mình sẽ tạo mới một Maven project để làm ví dụ:

JSON Binding trong Jakarta EE

  JSON-LD là gì ? Tổng quan về JSON-LD cho người mới

Eclipse Yasson dependency như sau:

Để làm ví dụ, mình sẽ định nghĩa một class Student chứa thông tin sinh viên như sau:

Student student = new Student("Khanh", 35);

Để convert đối tượng Student này qua chuỗi JSON, các bạn cần khởi tạo đối tượng của class Jsonb từ class JsonbBuilder của JSON Binding API như sau:

Implementation của những class này trong thư viện Yasson lần lượt là JsonBinding và JsonBindingBuilder.

Xem thêm các việc làm JSON hấp dẫn trên TopDev

Sau khi đã có đối tượng Jsonb thì chúng ta có thể sử dụng phương thức toJson() với tham số là đối tượng cần convert qua chuỗi JSON để convert nó qua JSON data:

String result = jsonb.toJson(student);

Toàn bộ code như sau:

package com.huongdanjava.jakartaee;

import jakarta.json.bind.Jsonb;
import jakarta.json.bind.JsonbBuilder;

public class Main {

  public static void main(String[] args) {
    Student student = new Student("Khanh", 35);

    Jsonb jsonb = JsonbBuilder.create();
    String result = jsonb.toJson(student);
    System.out.println(result);
  }
}

Kết quả khi chạy ứng dụng ví dụ này như sau:

JSON Binding trong Jakarta EE

Nếu các bạn có chuỗi JSON cho thông tin sinh viên và cần convert nó qua đối tượng Student, các bạn cũng có thể sử dụng phương thức fromJson() để làm điều này.

Ví dụ mình có chuỗi JSON chứa thông tin sinh viên như sau:

String json = "{\"age\":20,\"name\":\"Thanh\"}";

Mình có thể convert qua đối tượng Student như sau:

Kết quả:

JSON Binding trong Jakarta EE

  Chuyển đổi JSON qua CSV sử dụng thư viện Jackson

Các bạn có thể định nghĩa đối tượng của class JsonConfig để thêm một số cấu hình về chuỗi JSON sẽ được generate. Ví dụ như nếu các bạn muốn output JSON được format thì các bạn có thể viết code như sau:

package com.huongdanjava.jakartaee;

import jakarta.json.bind.Jsonb;
import jakarta.json.bind.JsonbBuilder;
import jakarta.json.bind.JsonbConfig;

public class Main {

  public static void main(String[] args) {
    Student student = new Student("Khanh", 35);

    JsonbConfig config = new JsonbConfig()
        .withNullValues(true)
        .withFormatting(true);

    Jsonb jsonb = JsonbBuilder.create(config);
    String result = jsonb.toJson(student);
    System.out.println(result);
  }
}

Kết quả:

JSON Binding trong Jakarta EE

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

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

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

Quy tắc BEM trong CSS – Bạn không cần phải đau đầu với cách đặt tên class nữa

bem trong css

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

Chào các bạn,

Bạn có bao giờ code CSS mà không biết phải đặt tên class như thế nào không? Mình thì có đấy. Nhất là khi maintain dự án, mất bao nhiêu công mới nghĩ ra được cái tên hay thì lại bị người người trước dùng mất rồi. Tự nghĩ Code CSS thì nên tập trung vào việc căn chỉnh các thuộc tính, chứ không nên mất nhiều thời gian vào cách đặt tên, nên mình đã đi tìm hiểu xem có cái quy tắc nào trong cách đặt tên không, để rồi cứ theo quy tắc là làm, đỡ phải nghĩ nhiều.

Sau một hồi lục sục trên mạng, mình thấy có cái quy tắc BEM này khá hay nên viết bài để chia sẻ tới mọi người.

I. Quy tắc BEM là gì?

BEM là viết tắt của Block Element Modifiers – một quy tắc giúp bạn đặt tên các selector của CSS.

Block Element Modifiers nghĩa là “Khối – Phần tử – Biến thể”, dịch ra Tiếng Việt nghe không được sát nghĩa và có vẻ không “chuyên nghiệp”, nên thôi mình cứ để Tiếng Anh nhé.

Với quy tắc BEM, nó sẽ chia các class css ra làm 3 loại:

  • class định nghĩa cho một block
  • class định nghĩa cho các element trong block
  • class định nghĩa các “biến thể” cho block hoặc cho element trong block.

Rắc rối nhỉ, thôi thì xem cái ví dụ này để dễ hiểu hơn bạn nhé.

  Cảm giác khi bạn viết CSS như thế nào trong năm 2024

  Tổng hợp CSS tips tricks hay mà có thể bạn chưa biết

CSS viết theo quy tắc BEM

/* class định nghĩa một block */
.product { }

/* class định nghĩa element của block */
.product__title { }
.product__description { }
.product__image { }

/* class định nghĩa các "biến thể" của block */
.product--style-1 { }
.product--big { }
.product--small { }
.product__title--style-1 { }

HTML sử dụng CSS viết theo quy tắc BEM

<div class="product product--small">
    <div class="product__image">
        <img src="..." alt="">
    </div>
    <div class="product__title product__title--style-1">Iphone 11 Pro</div>
    <div class="product__description">Siêu đắt</div>
</div>

Từ hai đoạn code trên bạn có thể thấy:

  • product là một block, style của nó được định nghĩa thông qua class .product
  • .product__title.product__image.product__description lần lượt là các class element.
  • .product--style-1.product--big.product--small.product__title--style-1 là các class “biến thể”.

Tổng quát lại, chúng ta có thể thấy một class viết theo quy tắc BEM sẽ có cấu trúc như sau

Block__Element--Modifier

Với cách đặt tên kiểu này, các css selector sẽ khó mà trùng nhau được

Tham khảo việc làm CSS hấp dẫn trên TopDev

II. Lợi ích khi sử dụng BEM

Lợi ích mà ai cũng thấy được ngay đó là BEM giúp chúng ta giảm khả năng 2 css selector bị trùng nhau – giống như ngay từ đầu mình đề cập. Nhưng ngoài ra, BEM còn có một số lợi ích khác:

  • Giúp bạn hình dung ra được cấu trúc của một block HTML sẽ sử dụng các class này.
  • Dễ dàng nắm bắt được các thành phần phụ thuộc lẫn nhau.
  • Với BEM, nó làm “phẳng” các class, không có sự lồng cấp kiểu .a .b .c, giúp bạn không cần phải để ý tới độ ưu tiên (specificity) khi code css.
  • Giảm công sức của developer trong việc phải cố nghĩ ra một cái tên vừa hay vừa chưa tồn tại.

Ngoài các lợi ích kể trên, BEM còn phù hợp để triển khai với SCSS

Ví dụ: Vẫn là đoạn CSS ở ví dụ trên, nhưng giờ mình viết theo SCSS.

.product {
    &__title {
        &--style-1 { }
    }

    &__description { }
    &__image { }

    &--style-1 { }
    &--big { }
    &--small { }
}

III. Một số ý kiến không đồng tình với quy tắc BEM

Dù có nhiều lợi ích, nhưng có nhiều người không thích dùng quy tắc này vì

Nó dài và xấu

Mình công nhận điều này, nếu không cận thận bạn sẽ có .Mot-cai-class__dai--ngoang-ngoang-the-nay.

Nhưng dài mà mang đủ ý nghĩa, đảm bảo không bị trùng thì cũng không sao. Còn xấu thì… nhìn nhiều khắc quen.

Nó có vẻ không cần thiết

Quay trở lại với ví dụ ở phần đầu, mình có thể viết CSS không tuân theo quy tắc BEM và vẫn đáp ứng được một số lợi ích của BEM như sau:

.product { }

.product .title { }
.product .description { }
.product .image { }

.product.style-1 { }
.product.big { }
.product.small { }
.product .title.style-1 { }

Nhìn còn có vẻ gọn ngàng hơn đấy chứ, nhưng khi dự án phát triển tới một “cảnh giới” nhất định thì liệu bạn có chắc chắn các class sẽ không bị đặt tên chồng chéo không? Giả sử ở đâu đó trong project đã có ai đó định nghĩa các class .title.image.description rồi thì sao?

// Ai đó đã định nghĩa trước các selector thế này
.title { }
.description { }
.image { }

Không biết bạn có cảm thấy không hài lòng với BEM ở chỗ nào không?

IV. Tổng kết

Tổng kết lại thì:

  • BEM là quy tắc đặt tên class cho CSS, mang lại nhiều lợi ích nhưng quan trọng vẫn là giúp developer bớt phải nghĩ ra cái tên vừa hay vừa chưa được sử dụng.
  • BEM sẽ tuyệt vời hơn khi sử dụng với SCSS
  • Có nhiều người không thích BEM vì nó làm tên class dài và xấu, hoặc họ tự có phương pháp khác thay thế BEM.

Còn bạn thế nào, bạn có thấy BEM cần thiết trong dự án của mình không? Hãy để lại comment cho mình biết với.

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

Xem thêm:

Xem thêm công việc CNTT hấp dẫn trên TopDev