Chinh phục công nghệ: Nhóm anh tài ngôn ngữ lập trình Go

Ngôn ngữ lập trình Go, được phát triển bởi Google, đã tạo nên một làn sóng mới trong giới lập trình viên bởi sự đơn giản và hiệu quả. Ở Sun*, Go ngày càng chiếm vai trò quan trọng trong các dự án lớn. 4 kỹ sư công nghệ có kinh nghiệm thực chiến dày dặn với Go sẽ chia sẻ 1 số bí kíp của họ trong việc chinh phục ngôn ngữ lập trình này tới chúng ta ngay dưới đây.

Đăng Quân: "Chú ý tới quản lý lỗi và những điểm khác biệt của Go"

Vào thời điểm cuối năm 2017 - đầu năm 2018, là thời điểm bắt đầu xuất hiện các trend công nghệ như microservice, container, K8S tại thị trường Việt Nam sau khi có rất nhiều công ty trên quốc tế áp dụng thành công. Ở thời điểm đó thì mình vẫn đang chỉ lập trình các ứng dụng monolith bằng ngôn ngữ lập trình Java. Mình bắt đầu tìm hiểu xem kiến trúc microservice và container có những ưu điểm gì. Qua quá trình tìm hiểu, và tham gia các diễn đàn, đọc các tin tức về công nghệ thì mình cũng có biết về thông tin vụ kiện giữa Oracle và Google về bản quyền sử dụng các Java API trên Android OS, và rồi thông tin về việc Google ra mắt ngôn ngữ lập trình Go như một giải pháp thay thế cho Java xuất hiện. Trùng hợp thay là Go chính là ngôn ngữ xây dựng lên các container runtime phổ biến, cũng như một công cụ điều phối container nổi tiếng là K8S. Vậy là mình bắt đầu tìm hiểu xem ngôn ngữ lập trình này có gì đặc biệt so với Java và cũng bắt đầu chuyển sang sử dụng ngôn ngữ này làm ngôn ngữ lập trình chính cho đến bây giờ.

Trong quá trình tìm hiểu và sử dụng ngôn ngữ lập trình Go, mình nhận thấy ngôn ngữ lập trình này có các ưu điểm như:

  - Cú pháp đơn giản, ngắn gọn, dễ học và rất quen thuộc đối với các bạn đang sử dụng các ngôn ngữ lập trình họ C như C, C++, Java, C#,...

  - Mã code được biên dịch trực tiếp ra file binary, cross platform mà không cần Virtual Machine do ngôn ngữ hỗ trợ sẵn việc build ra file thực thi thuộc các hệ điều hành và kiến trúc phần cứng khác nhau.

  - Thời gian biên dịch mã code nhanh.

  - Trình thu dọn rác hoạt động với độ trễ thấp.

  - Các thư viện chuẩn được tích hợp sẵn bên trong ngôn ngữ cực kỳ phong phú.

  - Lịch trình phát hành phiên bản rõ ràng, các phiên bản sau tương thích với phiên bản trước.

  - Tương thích tốt với môi trường container, triển khai lên môi trường container rất đơn giản mà không cần cài đặt thêm các thư viện thứ 3, cũng như không có Virtual Machine chạy bên trong môi trường container giống như JVM của Java. Các file Docker image được build ra có kích thước nhỏ.

  - Hỗ trợ mạnh lập trình đồng thời nhưng đơn giản trong cách sử dụng.

  - Là một static typed language nên giúp sớm phát hiện lỗi trong quá trình biên dịch.

Ngoài những ưu điểm trên thì theo mình Go có thể đem lại một vài điểm “khó chịu” cho những bạn chuyển từ một ngôn ngữ khác sang như:

  - Trong ngôn ngữ lập trình Go, error được coi như là một giá trị kết quả được dự đoán trước, và nó có thể được sử dụng như những giá trị bình thường khác. Vì vậy việc kiểm tra error có thể diễn ra thường xuyên, khiến người lập trình mới có thể cảm thấy nhàm chán.

  - Tuy không có khái niệm exception, nhưng Go có khái niệm "panic", và khi để một panic xảy ra thì nó sẽ dẫn đến crash app ngay lập tức. Để tránh trường hợp này thì ta cần một function recover. Đối với một người mới chưa có kinh nghiệm thì trường hợp này có thể diễn ra và gây incident trên môi trường production.

  - Zero value và nil pointer

  - Với tiêu chí đơn giản nên sẽ không có nhiều "magic" giống như những ngôn ngữ lập trình khác.

Với nguyên tắc làm mọi thứ trông thật đơn giản trong tiêu chí thiết kế ngôn ngữ Go của Google, thì mình cho rằng nếu các bạn có dự định học Go thì chỉ cần nắm thật chắc kiến thức nền tảng của ngôn ngữ lập trình hiện tại, khi đó chuyển sang Go là vô cùng dễ dàng. 

- Đăng Quân -

Hoàng Phương: Vấn đề Concurrency chưa bao giờ là đơn giản! 

Mình bắt đầu với Go bằng các dự án cá nhân nho nhỏ, chủ yếu vì đây là một ngôn ngữ rất đơn giản, không cần framework hay thư viện phức tạp. Các dự án viết bằng Go nhờ vậy nên cũng rất dễ đọc hiểu, có thể dễ dàng học và làm theo, từ các thư viện nhỏ đến các dự án lớn đang có hàng triệu người sử dụng. Lúc đầu thì mình chỉ sử dụng Go như một ngôn ngữ để code trong lúc rảnh rỗi. Sau đó khi phiên bản 1.11 ra mắt với tính năng go modules rất được mong chờ, đúng lúc bộ phận có dự án mới rất phù hợp với Go nên mình đề xuất dùng luôn.

Go có nhiều ưu điểm mà có lẽ mọi người đều có thể search được. Bởi vậy, mình sẽ tập trung nhiều hơn vào nhược điểm của Go. Đó là: 

- Các tính năng mới ít được thêm vào ngôn ngữ vì muốn đảm bảo tính đơn giản.

- Ngôn ngữ đơn giản nên không có cách cú pháp rút gọn thường thấy trong các ngôn ngữ như Java, C#, JavaScript.

- Cơ chế xử lý lỗi cần thời gian làm quen. 

Bạn vẫn sẽ gặp lại những lỗi quen thuộc như Nil pointer dereference. Ngoài ra, Go hỗ trợ concurrency một cách dễ dàng nhưng bản thân vấn đề concurrency chưa bao giờ là đơn giản nên bạn vẫn sẽ phải lưu ý những lỗi thường gặp sau

  • Memory Leaks trong Goroutines -> Giải pháp: Luôn có cơ chế cancel/timeout & Sử dụng context để quản lý lifecycle.
  • Race Conditions -> Giải pháp: Sử dụng mutex hoặc channels.

Ứng dụng của Go rất rộng rãi và hiện đang được quan tâm trong những mảng tiềm năng như Microservices, Cloud-Native, DevOps, IoT nên trong tương lai gần chắc chắn Go vẫn là một trong những lựa chọn hàng đầu nếu bạn muốn bắt đầu một dự án mới. Cộng đồng Go cũng đang mở ra những hướng phát triển rất tiềm năng như xử lý dữ liệu, AI/ML. Tương lai của ngôn ngữ vẫn sẽ chú trọng đến những tính năng giúp tăng trải nghiệm của developer đúng như mục tiêu ban đầu. Ngoài ra các framework, thư viện chú trọng vào những mảng cụ thể như phát triển web cũng dần được quan tâm hơn để mang lại trải nghiệm tốt hơn cho các developer đến từ những ngôn ngữ khác.

Để bắt đầu học Go thì cách tốt nhất là bắt tay vào code với A Tour of Go trên Golang playground. Chỉ sau một loạt tutorial đơn giản là bạn đã nắm được gần như toàn bộ các cú pháp chính của ngôn ngữ rồi. Sau đó bạn có thể học thêm các ví dụ từ Go by Example Việc còn lại là học cách xây dựng ứng dụng thôi. Bạn có thể học từ các project lớn nhỏ trên GitHub. Quan trọng là đừng cố gắng áp dụng các pattern từ những ngôn ngữ bạn đã biết. Trong quá trình học bạn sẽ nhanh chóng làm quen với các pattern của Go thôi.

Ngọc Phương: "Kiểm soát tốt việc sử dụng goroutines và channels để tránh rò rỉ tài nguyên"

Mình bắt đầu học Go khi đối mặt với vấn đề về performance trong một hệ thống microservices. Mình đã tìm hiểu về Go và thấy rằng nó là một ngôn ngữ đơn giản và nổi bật với khả năng quản lý concurrency hiệu quả. Bên cạnh đó, mình cũng muốn tìm hiểu một ngôn ngữ mới với cách tiếp cận khác biệt so với những ngôn ngữ đã sử dụng trước đây như JavaScript và PHP.

Sự đơn giản, hiệu quả và khả năng quản lý concurrency của Go là những điểm mà mình rất ấn tượng. Các tính năng như goroutines và channels giúp mình quản lý luồng công việc song song một cách dễ dàng và hiệu quả mà không cần tốn quá nhiều effort. Điều này rất quan trọng trong việc nâng cao hiệu suât của các hệ thống backend trong khi vẫn giữ được sự đơn giản và dễ bảo trì.

Trong quá trình sử dụng Go thì chúng ta có thể thấy 1 số nhược điểm như:

- Thiếu đi một số tính năng hiện đại như generics, trait,... Go 1.18 đã bổ sung generics nhưng vẫn còn hạn chế.

- Hệ sinh thái còn đang phát triển, một số thư viện chưa đa dạng so với các ngôn ngữ phổ biến hơn như JavaScript hay Python.

Một bài học quan trọng là phải kiểm soát tốt việc sử dụng goroutines và channels để tránh rò rỉ tài nguyên. Nên hạn chế việc tạo goroutines không cần thiết, và sử dụng profiling tools của Go để tìm và tối ưu các bottlenecks.

Một lỗi mình thường gặp là deadlock khi sử dụng channels không cẩn thận. Để khắc phục, mình luôn cẩn thận trong việc thiết kế luồng dữ liệu và sử dụng công cụ go vet để phát hiện các vấn đề tiềm ẩn.

Go vẫn sẽ phát triển mạnh trong lĩnh vực microservices và các hệ thống yêu cầu concurrency cao. Với sự hỗ trợ ngày càng tốt và sự tham gia của các công ty/cộng đồng lớn, Go sẽ tiếp tục phát triển mạnh mẽ trong tương lai.

Cách học tốt nhất là bắt tay vào thực hành ngay với các dự án nhỏ và đọc kỹ các tài liệu chính thức của Go. Ngoài ra, tham gia các cộng đồng Go sẽ giúp các bạn nhanh chóng làm quen với các best practices và xử lý các vấn đề thường gặp.

Hữu Kim: "Làm chủ sự đơn giản của Go"

Mình bắt đầu tiếp cận Go trong một dự án yêu cầu khả năng thực thi một chương trình do người dùng viết. Có thể các bạn đã từng nghe tới nó có tên là Viblo Code. Người dùng viết code để giải bài tập. Bài toán đặt ra ở đây là cần "chạy" bài giải (source code) của người dùng gửi lên một cách nhanh chóng, an toàn và cần khả năng thực thi song song nhiều bài giải. Nghĩa là yêu cầu xử lý song song thì còn cần phải cô lập được môi trường thực thi code với môi trường của server và các các chương trình khác nhau. Và Go là ngôn ngữ lập trình được dự án lựa chọn. 

Ngay khi tiếp cận Go, mình thấy nó có cú pháp đơn giản, dễ đọc nhưng lại có khả năng xử lý song song tốt nhờ vào Goroutines và hệ thống channel. Cũng nhờ đặc tính này, mình đã nhanh chóng làm quen và bắt đầu triển khai ứng dụng với Go. Ngoài ra, kho thư viện của Go vào thời điểm đó cũng đã rất phong phú, nhiều sản phẩm opensource lớn viết bằng Go như Docker, K8s, .etc. 

Về ưu điểm của Go có thể kể đến như: 

  • Hiệu năng cao: Performance benchmark vượt trội so với nhiều ngôn ngữ lâu đời.
  • Xử lý song song tốt: Nhờ cơ chế Goroutines và channel đơn giản nhưng hiệu quả.
  • Tốc độ build nhanh: Build thành file binary tiện lợi, hỗ trợ live-reloading.
  • Hỗ trợ đa nền tảng: Build ứng dụng chạy trên Linux, Windows, MacOS.
  • Thư viện mạnh mẽ: GoReleaser tự động hóa quy trình release, hỗ trợ các package manager như Homebrew, Chocolately.

Về nhược điểm của Go: 

  • Thiếu tính năng nâng cao: Không có annotation, operator overloading, ternary operator.
  • Hạn chế OOP: Không có khái niệm class hay kế thừa, thay vào đó sử dụng struct và embedding.
  • Quản lý bộ nhớ: Garbage collection tiêu tốn tài nguyên runtime, có nguy cơ memory leak và stop-the-world.
  • Đơn giản hóa quá mức: Một số tính năng phổ biến trong các ngôn ngữ khác bị loại bỏ để giữ sự đơn giản, đôi khi gây bất tiện cho lập trình viên.

Một trong những dự án mình đã triển khai thành công với Go cũng chính là Viblo Code, dự án mà mình bắt đầu tìm hiểu về Go. Cụ thể, Go được ứng dụng vào trong việc phát triển service Viblo Code Runner. Viblo Code Runner đã đảm nhiệm tốt việc kiểm soát và chạy đồng thời các bài giải của người dùng dưới dạng các container được cô lập với môi trường thật. Đóng vai trò cung cấp môi trường an toàn trong việc thực thi code, góp phần thành công cho các cuộc thi lập trình (Code Contest) được tổ chức trên Viblo Code. Có thể kể đến như Code Contest 2020 mừng cộc mốc 5 năm của Viblo, với sự tham gia thi đấu của 222 đội thi cùng lúc. Đối với các task về tối ưu hóa performance, phương châm của mình là "không làm mò", nên thực hiện kỹ thuật profiling ứng dụng để có cái nhìn tổng quan rồi từ đó làm căn cứ khoanh vùng những chỗ mà mình thấy số liệu có vấn đề. Go có cung cấp sẵn công cụ có tên là pprof, hỗ trợ mình trong việc đo đạc để tìm xem vấn đề nằm ở CPU, Heap / Memory, Goroutine hay vấn đề khác. 

Cho tới hiện tại, tiềm năng của Go thì không cần phải bàn cãi mà đã được cộng đồng công nhận. Các bạn có thể thấy nhiều dự án lớn trong hệ sinh thái Kubernetes đều viết bằng Go. Trong Tech Whitepaper của Sun*, chúng mình cũng dẫn chứng nhiều số liệu để so sánh performance và sức hấp dẫn mà Go mang lại. Mình thấy, Go rất dễ học. Đặc biệt là khi bạn đã thành thạo sử dụng một ngôn ngữ lập trình trước đó. Mình nghĩ chỉ trong vòng 1 tuần là các bạn PHP Dev đã có thể tham gia code Go được. Có chăng các bạn có thể thấy hơi bỡ ngỡ khi một số tính năng nâng cao bị thiếu, hoặc điển hình đó là OOP trong Go đôi chút sẽ khác với trong PHP, Java. Có một trang web rất hay thực hiện tóm tắt về syntax của các ngôn ngữ lập trình, đối với Go là https://learnxinyminutes.com/docs/go/ nó sẽ giúp các bạn Dev nhanh chóng nắm được syntax của Go, các cấu trúc rẽ nhánh và các kiểu dữ liệu. Sau tuần đầu tiên, các bạn nên tìm hiểu về cách sử dụng một số framework để build ứng dụng. Mình recommend cobra cho việc xây dựng CLI, echo framework để xây dựng web và tiếp tục đào sâu hơn về Go.

Hành trình với Go của các chuyên gia tại Sun* cho thấy sự phát triển không ngừng và tầm quan trọng của việc nắm bắt các công nghệ mới. Go không chỉ đơn giản mà còn mạnh mẽ, đủ để chinh phục bất kỳ hệ thống phức tạp nào. Qua những chia sẻ quý giá này, hy vọng các lập trình viên sẽ có thêm động lực để thử sức và khai phá những tiềm năng mà Go mang lại.

#học ngôn ngữ lập trình mới

#Ngôn ngữ Go