Golang course syllabus

Buổi 1: Giới thiệu về Ngôn Ngữ Go (45 phút)

Mục tiêu bài học:

  • Hiểu sơ lược về lịch sử và đặc điểm của ngôn ngữ Go.

  • Nắm được những ưu điểm của Go so với các ngôn ngữ khác.

  • Sử dụng các công cụ godocgo doc để tìm kiếm tài liệu.

  • Biên dịch và chạy các chương trình Go đơn giản.

  • In ra màn hình và lấy dữ liệu từ người dùng.

  • Làm việc với tham số dòng lệnh.

  • Sử dụng tệp nhật ký (log files).

  • Phát triển phiên bản cơ bản của ứng dụng danh bạ điện thoại.

Nội dung chi tiết (45 phút):

1. Giới thiệu (5 phút):

  • Giảng viên chào hỏi và giới thiệu bản thân.

  • Giới thiệu về ngôn ngữ Go, nguồn gốc và lịch sử phát triển.

2. Đặc điểm của Go (5 phút):

  • Ngôn ngữ gõ tĩnh (statically typed).

  • Dịch sang mã trung gian (compiled language).

  • Ngôn ngữ cấp cao (high-level language).

  • Ngôn ngữ đơn giản, dễ học và dễ đọc.

  • Hỗ trợ tốt cho việc phát triển đồng thời (concurrency).

  • Thích hợp cho phát triển các ứng dụng web, hệ thống phân tán và các ứng dụng Cloud.

3. Ưu điểm của Go (5 phút):

  • Nhanh chóng: Dịch và chạy chương trình Go diễn ra rất nhanh.

  • Đơn giản: Ngôn ngữ dễ học, cú pháp rõ ràng, dễ hiểu.

  • Hiệu quả: Hỗ trợ tốt cho việc quản lý bộ nhớ, giúp viết code hiệu quả.

  • Đồng thời: Thích hợp xây dựng các ứng dụng xử lý nhiều tác vụ cùng lúc.

  • Thư viện chuẩn: Go cung cấp nhiều thư viện chuẩn phong phú cho nhiều tác vụ.

  • Cộng đồng: Go có cộng đồng người dùng lớn và hoạt động tích cực.

4. Tìm kiếm tài liệu (5 phút):

  • Giới thiệu công cụ godoc để tìm kiếm tài liệu trực tuyến về Go.

  • Thực hành sử dụng godoc để tìm kiếm thông tin về các package và function.

  • Giới thiệu công cụ go doc để xem tài liệu về các package và function được cài đặt cục bộ.

  • Thực hành sử dụng go doc để xem tài liệu về các package và function có sẵn.

5. Biên dịch và chạy chương trình (10 phút):

  • Giới thiệu về các bước biên dịch và chạy chương trình Go.

  • Thực hành viết một chương trình Go đơn giản để in ra màn hình.

  • Sử dụng dòng lệnh go run để biên dịch và chạy chương trình.

  • Giải thích về file source code với đuôi .go.

  • Giải thích về file biên dịch với đuôi .exe (trên Windows) hoặc binary (trên các hệ điều hành khác).

6. In/Xuất dữ liệu (5 phút):

  • Giới thiệu hàm fmt.Println để in ra màn hình.

  • Thực hành sử dụng fmt.Println để in ra các nội dung khác nhau (string, number, v.v.).

  • Giới thiệu về việc đọc dữ liệu từ người dùng bằng hàm fmt.Scanln.

  • Thực hành sử dụng fmt.Scanln để lấy dữ liệu do người dùng nhập vào.

7. Tham số dòng lệnh (5 phút):

  • Giới thiệu về tham số dòng lệnh (command-line arguments).

  • Truyền tham số dòng lệnh vào chương trình Go.

  • Thực hành viết chương trình Go nhận tham số dòng lệnh và in ra màn hình.

  • Giải thích về mảng os.Args để truy cập các tham số dòng lệnh.

8. Tệp nhật ký (log files) (5 phút):

  • Giới thiệu về khái niệm tệp nhật ký (log file).

  • Giới thiệu package log để ghi log trong chương trình Go.

  • Thực hành sử dụng package log để ghi thông tin ra file nhật ký.

  • Giải thích về các mức độ log khác nhau (debug, info, error, v.v.).

9. Ứng dụng danh bạ điện thoại (5 phút):

  • Giới thiệu về ứng dụng danh bạ điện thoại đơn giản.

  • Thực hành xây dựng phiên bản cơ bản của ứng dụng danh bạ.

  • Ứng dụng sẽ lưu trữ thông tin tên và số điện thoại của các liên lạc.

  • Thực hành thêm/xóa/tìm kiếm liên

Buổi 2: Các data type cơ bản

Mục tiêu bài học:

  • Nắm vững các kiểu dữ liệu cơ bản trong Go (kiểu số và kiểu không phải số).

  • Hiểu khái niệm và cách sử dụng Arrays và Slices.

  • Làm việc với con trỏ (pointers) trong Go.

  • Sử dụng hằng số (constants).

  • Xử lý ngày tháng và thời gian.

  • Tạo dữ liệu ngẫu nhiên và áp dụng cho ứng dụng danh bạ điện thoại.

Nội dung chi tiết (45 phút):

1. Các kiểu dữ liệu cơ bản trong Go (20 phút)

  • Kiểu số:

    • Các kiểu số nguyên: int8, int16, int32, int64, uint8, uint16, uint32, uint64 (đại diện cho số nguyên có/không dấu)

    • Các kiểu số thực: float32, float64

    • Thực hành chuyển đổi giữa các kiểu số.

  • Kiểu Boolean:

    • bool: đại diện cho giá trị đúng/sai (true / false).

    • Thực hành sử dụng giá trị boolean với các toán tử so sánh/logic.

  • Kiểu ký tự (rune):

    • rune: Dùng để biểu diễn ký tự Unicode.

    • Thực hành với các phép xử lý ký tự cơ bản.

  • Kiểu chuỗi:

    • string: lưu trữ chuỗi ký tự.

    • Thực hành nối chuỗi, cắt chuỗi và tìm kiếm trong chuỗi.

2. Arrays và Slices (10 phút):

  • Arrays:

    • Khái niệm về arrays - mảng lưu trữ các phần tử cùng kiểu dữ liệu.

    • Cách khai báo và khởi tạo arrays.

    • Truy cập và thay đổi phần tử trong array.

  • Slices:

    • Khái niệm slices - một vùng có thể điều chỉnh kích thước của một array.

    • Cách tạo slices và các thao tác cơ bản trên slices (thêm, cắt, lặp...)

    • So sánh arrays và slices.

3. Con trỏ (Pointers) (5 phút):

  • Khái niệm con trỏ - biến chứa địa chỉ bộ nhớ của một giá trị.

  • Cách khai báo và lấy giá trị thông qua con trỏ.

  • Ứng dụng cơ bản của con trỏ (truyền tham số theo tham chiếu)

4. Hằng số (Constants) (5 phút):

  • Khai báo hằng số với từ khoá const.

  • Các kiểu dữ liệu hỗ trợ làm hằng số.

  • Những giá trị không thay đổi trong suốt chương trình.

5. Ngày/Giờ (5 phút):

  • Giới thiệu package time

  • Khai báo biến kiểu ngày/giờ.

  • Thực hành lấy thời gian hiện tại, định dạng ngày/giờ.

  • Các thao tác cơ bản với ngày/giờ (tính khoảng thời gian, so sánh, v.v.).

6. Tạo dữ liệu ngẫu nhiên và hoàn thiện ứng dụng danh bạ (5 phút):

  • Giới thiệu về package rand để tạo số ngẫu nhiên.

  • Tạo dữ liệu ngẫu nhiên cho tên và số điện thoại trong danh bạ.

  • Tích hợp vào ứng dụng danh bạ hiện có.

Bài tập:

  • Thực hành viết các ví dụ ngắn với từng kiểu dữ liệu.

  • Tạo ứng dụng nhỏ sử dụng tính năng ngày/giờ

  • Thêm chức năng cho ứng dụng danh bạ điện thoại:

    • Cho phép chỉnh sửa thông tin liên lạc.

    • Lưu trữ danh bạ vào một file.

Buổi 3: Composite Data Types

Mục tiêu bài học:

  • Hiểu và làm việc với các kiểu dữ liệu tổng hợp (Maps, Structs).

  • Nắm được khái niệm về Biểu thức Chính quy (Regular Expressions) và ứng dụng của nó.

  • Đọc và ghi tập tin CSV.

  • Cải thiện ứng dụng danh bạ điện thoại với khả năng lưu dữ liệu bền vững.

Nội dung chi tiết (45 phút):

1. Maps (15 phút):

  • Khái niệm về Maps (còn gọi là Dictionary): Cấu trúc dữ liệu lưu trữ cặp key-value (không có thứ tự).

  • Tạo maps, thêm/xóa/sửa phần tử trong map.

  • Lặp qua các phần tử trong Map.

  • Các use case điển hình của Maps.

2. Structs (15 phút):

  • Khái niệm về Structs: kiểu dữ liệu do người dùng tự định nghĩa để gom nhóm các thuộc tính có kiểu dữ liệu khác nhau.

  • Khai báo struct sử dụng từ khóa struct.

  • Cách khởi tạo giá trị cho các thuộc tính (field) của một struct.

  • Truy cập và sửa đổi các thuộc tính của struct.

  • Nhúng struct (struct lồng nhau) và các ứng dụng nâng cao.

3. Biểu thức Chính quy (Regular Expressions) (5 phút):

  • Giới thiệu package regexp trong Go.

  • Khái niệm Biểu thức Chính quy (Regular Expressions) - định dạng mẫu (pattern) cho việc xử lý văn bản.

  • Cách viết các biểu thức chính quy cơ bản.

  • Tìm kiếm và thay thế văn bản dựa trên biểu thức chính quy.

4. Đọc/Ghi tệp CSV (10 phút):

  • Giới thiệu định dạng tệp CSV (Comma-Separated Values)

  • Đọc dữ liệu từ tệp CSV bằng package encoding/csv.

  • Ghi dữ liệu ra tệp CSV.

  • Ứng dụng: đọc và ghi dữ liệu của ứng dụng danh bạ từ/vào tệp CSV.

5. Hoàn thiện ứng dụng danh bạ: lưu trữ bền vững (5 phút):

  • Tích hợp cơ chế đọc danh bạ từ file CSV khi khởi động ứng dụng.

  • Lưu danh bạ vào file CSV trước khi kết thúc ứng dụng.

Bài tập:

  • Thực hành các ví dụ với Maps và Structs trong các ngữ cảnh khác nhau.

  • Viết một chương trình nhỏ để kiểm tra tính hợp lệ của định dạng email bằng biểu thức chính quy.

  • Thêm chức năng lưu và tải dữ liệu danh bạ bằng tệp CSV.

Buổi 4: Reflection and Interfaces

Mục tiêu bài học:

  • Hiểu các khái niệm quan trọng: Reflection, Interfaces, Phương thức gắn với kiểu dữ liệu (Type Methods).

  • Ứng dụng empty interface, xác nhận kiểu (type assertions), type switches.

  • Hiểu về interface error và cách xử lý lỗi trong Go.

  • Làm quen với việc Go có thể mô phỏng một số khái niệm hướng đối tượng.

  • Tiếp tục nâng cao ứng dụng danh bạ điện thoại.

Nội dung chi tiết (45 phút):

1. Reflection (10 phút):

  • Khái niệm Reflection: Khả năng kiểm tra kiểu dữ liệu và thông tin metadata của một biến tại thời gian chạy (runtime).

  • Giới thiệu package reflect.

  • Cách sử dụng reflect.TypeOf để lấy kiểu dữ liệu của một biến.

  • Lấy các thuộc tính (field) của một struct dùng reflect.ValueOf.

2. Interfaces (20 phút):

  • Khái niệm Interfaces: Định nghĩa tập hợp các phương thức.

  • Cách khai báo và sử dụng interface.

  • Interface rỗng (empty interface - interface{}): có thể chứa giá trị của bất kỳ kiểu dữ liệu nào.

  • Xác nhận kiểu dữ liệu (Type Assertions): Kiểm tra xem một giá trị có thỏa mãn một interface cụ thể hay không.

  • Type switches: Rẽ nhánh logic dựa trên kiểu dữ liệu động (dynamic type) interface đang chứa.

3. Phương thức gắn với kiểu dữ liệu (Type Methods) (5 phút):

  • Gắn các hàm (hàm được gọi là phương thức) cho các kiểu dữ liệu cụ thể.

  • Thực thi các phương thức gắn với kiểu dữ liệu và cách chúng liên hệ tới interfaces.

4. Xử lý lỗi (Error handling) (5 phút):

  • Kiểu error và interface error: đại diện cho các tình huống lỗi.

  • Cơ chế trả về error trong hàm.

  • Cách kiểm tra và xử lý lỗi trong chương trình Go.

5. Hướng đối tượng trong Go (5 phút):

  • Go không hỗ trợ trực tiếp hướng đối tượng theo cách các ngôn ngữ OOP truyền thống.

  • Cách mô phỏng khái niệm kế thừa bằng cách nhúng structs.

  • Cách sử dụng Interface và Type Methods để mô phỏng tính đa hình.

6. Cải thiện ứng dụng danh bạ điện thoại (5 phút):

  • Thêm chức năng sắp xếp danh bạ theo tên.

  • Bổ sung tính năng tìm kiếm nhanh bằng tên (không phân biệt chữ hoa/thường).

Bài tập:

  • Viết ví dụ minh họa việc sử dụng Reflection cho những tình huống thực tế (ví dụ: hiển thị tất cả các thông tin của một struct, kể cả các trường private).

  • Tạo interface và sử dụng nó trong một ngữ cảnh đơn giản (ví dụ: tạo interface Shape với phương thức CalculateArea(), cài đặt cho các hình như Circle, Rectangle).

  • Cải thiện cách xử lý lỗi của ứng dụng danh bạ .

Lưu ý:

  • Học kỹ Interfaces, Type Assertions và Type Switches vì chúng khá quan trọng và có thể gây khó hiểu lúc đầu.

  • Học kỹ về sự khác nhau giữa lỗi (error) và panic trong Go.

Buổi 5: Go Packages and Functions

Mục tiêu bài học:

  • Nắm chắc về Packages, Modules, Functions trong Go.

  • Tạo một Go Package tương tác với cơ sở dữ liệu PostgreSQL.

  • Hiểu cách tạo tài liệu hướng dẫn (documentation) cho một package.

  • Sử dụng thành thạo từ khóa defer.

  • Tìm hiểu về GitLab Runners và GitHub Actions để tự động hóa tác vụ.

  • Đóng gói ứng dụng Go thành Docker Image.

Nội dung chi tiết (45 phút):

1. Packages, Modules và Functions (15 phút)

  • Ôn tập lại khái niệm về Package: cách gom nhóm các tệp code liên quan với nhau, tăng tính tái sử dụng.

  • Giới thiệu Module: cách nhóm các package có liên hệ, cung cấp cơ chế quản lý phiên bản.

  • Tạo file go.mod để quản lý modules của dự án.

  • Cách import và sử dụng các packages, các hàm (functions) đã viết trong các packages khác.

  • Quy tắc đặt tên và visibility (public/private) trong packages.

2. Tạo Go Package cho PostgreSQL (10 phút)

  • Cài đặt thư viện tương tác với PostgreSQL (ví dụ pq hoặc pgx).

  • Tạo Go package mới với các chức năng:

    • Kết nối đến cơ sở dữ liệu PostgreSQL.

    • Thực hiện các câu truy vấn cơ bản (SELECT, INSERT, UPDATE, DELETE).

    • Đóng kết nối đến cơ sở dữ liệu.

3. Tài liệu hướng dẫn cho Package (5 phút)

  • Sử dụng godoc để tạo tài liệu hướng dẫn cho package đã viết.

  • Cách viết chú thích (comments) trực tiếp trong code để godoc tạo tài liệu.

  • Tạo file README.md mô tả rõ ràng thông tin về package (mục đích, cách sử dụng, ví dụ,...).

4. Từ khóa defer (5 phút)

  • Giải thích hoạt động của từ khóa defer: Chạy một đoạn code ở thời điểm hàm (function) kết thúc.

  • Các ứng dụng điển hình của defer (đóng file, đóng kết nối, thực hiện dọn dẹp tài nguyên,...)

5. GitLab Runners và GitHub Actions (5 phút)

  • Giới thiệu hệ thống CI/CD (Continuous Integration/Continuous Deployment).

  • Khái niệm về GitLab Runners và GitHub Actions để tự động hóa chạy test, build code, triển khai.

  • Thiết lập flow đơn giản sử dụng GitLab Runners hoặc GitHub Actions để chạy test tự động.

6. Docker Image cho Go Binary (5 phút)

  • Giới thiệu về Docker và Docker Image.

  • Cách viết Dockerfile để đóng gói ứng dụng Go.

  • Build image từ Dockerfile và run ứng dụng trong container.

Bài tập:

  • Thực hành tạo một package đơn giản và viết tài liệu cho nó.

  • Mở rộng package cho PostgreSQL để hỗ trợ thêm các tác vụ phức tạp hơn.

  • Thiết lập GitHub Actions để tự động build và chạy test cho project.

Lưu ý:

  • Chuẩn bị sẵn một database PostgreSQL để sử dụng thử package.

  • Cân nhắc sử dụng một GitLab Runners hoặc GitHub Actions cho mục đích demo/học tập.

  • Docker và CI/CD là những phần tương đối rộng. Có thể tự học nâng cao thêm (ngoài phạm vi syllbus này)

Buổi 6: Telling a UNIX System What to Do

Mục tiêu bài học:

  • Sử dụng Go trong lập trình hệ thống (tương tác command-line, file, tín hiệu hệ điều hành).

  • Hiểu các interfaces io.Readerio.Writer.

  • Làm việc với các định dạng dữ liệu JSON, XML, YAML.

  • Tạo công cụ dòng lệnh tiện ích sử dụng các package cobraviper.

  • Nhúng tài nguyên vào Go binary.

Nội dung chi tiết (45 phút):

1. Lập trình Hệ thống với Go (15 phút)

  • Nhắc lại các thao tác với tham số dòng lệnh (package os).

  • Xử lý tín hiệu của hệ điều hành Unix (package os/signal): bắt các tín hiệu như tắt chương trình (SIGINT).

  • Thao tác với file: đọc (read) và ghi (write) file trong Go.

  • Khái niệm về interfaces io.Readerio.Writer.

2. JSON, XML, YAML (10 phút)

  • Giới thiệu các định dạng dữ liệu có cấu trúc JSON, XML, YAML và cách thức sử dụng phổ biến của mỗi loại.

  • Sử dụng package encoding/json, encoding/xml trong Go để làm việc với các định dạng này (biên mã - marshaling và giải mã - unmarshaling).

3. Tạo công cụ dòng lệnh (CLI) với cobraviper (10 phút)

  • Giới thiệu các package phổ biến hỗ trợ xây dựng công cụ dòng lệnh:

    • cobra: Cung cấp các lệnh (command), sub-command, flags, và cấu trúc cho ứng dụng CLI.

    • viper: Hỗ trợ quản lý thông tin cấu hình (configuration) từ nhiều nguồn (file config, environment variables, command-line flags)

  • Tạo ứng dụng dòng lệnh đơn giản để xem thông tin file (tên file, dung lượng, thời gian sửa đổi, v.v.).

4. Nhúng tài nguyên vào Go Binary (5 phút)

  • Khái niệm về việc nhúng file (ví dụ file template, file cấu hình) trực tiếp vào ứng dụng Go binary.

  • Cách sử dụng các công cụ hỗ trợ như go-bindata.

5. Ứng dụng danh bạ điện thoại (5 phút)

  • Chuyển đổi dữ liệu trong ứng dụng danh bạ sang lưu trữ định dạng JSON.

  • Cải tiến ứng dụng danh bạ thành một công cụ dòng lệnh sử dụng cobra (thêm các lệnh: add, list, delete, search).

Bài tập:

  • Tìm hiểu cách tương tác với tiến trình (process) khác từ chương trình Go.

  • Mở rộng ứng dụng dòng lệnh tìm thông tin file bằng cách thêm tính năng đệ quy đi sâu vào các thư mục.

  • Thêm chức năng đọc file cấu hình (ví dụ: định dạng YAML) cho ứng dụng danh bạ.

Lưu ý

  • Cung cấp sẵn các ví dụ đơn giản về JSON, XML, YAML.

  • Giải thích sự khác biệt giữa các package io, ioutil, os, và io/fs khi làm việc với hệ thống tập tin.

  • Tập trung vào các khái niệm và ý tưởng quan trọng hơn là các chi tiết cú pháp phức tạp khi giới thiệu cobraviper.

Buổi 7: Go Concurrency

Mục tiêu bài học:

  • Hiểu rõ khái niệm Goroutines, Channels, và Pipelines.

  • Nắm các kỹ thuật đồng bộ hóa cơ bản sử dụng package sync.

  • Biết cách sử dụng từ khóa select cùng channels.

  • Thảo luận về Mutexes (sync.Mutex, sync.RWMutex) và việc xử lý đồng bộ trên bộ nhớ chia sẻ (shared memory).

  • Hiểu cách vận hành của Go Scheduler.

  • Giới thiệu package context.

  • Tạo worker pools trong Go.

Nội dung chi tiết (45 phút):

1. Goroutines, Channels, Pipelines (15 phút)

  • Goroutines: Các hàm có thể chạy đồng thời, nhẹ hơn threads truyền thống.

  • Channels: Cơ chế giao tiếp và đồng bộ hóa giữa các goroutines.

  • Pipelines: Kỹ thuật lập trình đồng thời bằng cách nối các stages (goroutines) qua channels.

  • Ví dụ: Tạo goroutines, truyền/nhận dữ liệu qua channels, xây dựng một pipeline đơn giản.

2. Đồng bộ hóa và Go Scheduler (10 phút)

  • Đồng bộ hóa (Synchronization): Điều phối thứ tự, đảm bảo an toàn dữ liệu khi nhiều goroutines truy xuất tài nguyên cùng lúc.

  • Package sync: Cung cấp các công cụ cơ bản như sync.Mutex, sync.RWMutex.

  • Cách Go Scheduler hoạt động: Nguyên lý vận hành, quản lý & luân chuyển goroutines.

3. Từ khóa select (5 phút)

  • Sử dụng từ khóa select để quản lý nhiều kênh (channel) cùng lúc.

  • Các trường hợp ứng dụng: xử lý đồng thời nhiều kết quả, timeouts, ...

4. Package context (5 phút)

  • Giới thiệu package context để quản lý ngữ cảnh, tín hiệu trong các hệ thống đồng thời (ví dụ: cancellation- hủy xử lý, timeouts).

  • Cách tạo một context.Context và sử dụng nó trong các hàm.

5. Worker Pools (5 phút)

  • Mô hình Worker Pools: quản lý nhóm goroutines (workers) thực thi các tác vụ được đưa vào hàng đợi.

  • Lợi ích: Quản lý số lượng goroutines, tái sử dụng goroutines, kiểm soát tải.

6. Phát hiện Race Condition (5 phút)

  • Khái niệm Race Condition. Nguyên nhân và các vấn đề tiềm ẩn.

  • Công cụ trong Go để phát hiện Race Condition (Go Race Detector).

Bài tập:

  • Viết ứng dụng in ra các số nguyên tố trong một khoảng bằng cách sử dụng nhiều goroutines kết hợp channels.

  • Tìm hiểu và sử dụng sync.WaitGroup để đồng bộ hóa nhiều goroutines.

  • Thử nghiệm viết một worker pool đơn giản.

Buổi 8: Building Web Services

Mục tiêu buổi học:

  • Nắm chắc cách sử dụng package net/http để viết web server và web service.

  • Tạo web client tương tác với web service.

  • Tích hợp với Prometheus để thu thập các chỉ số (metrics) và sử dụng Grafana để trực quan hóa.

  • Cải tiến ứng dụng danh bạ thành một web service cùng với command-line client.

Nội dung chi tiết (45 phút):

1. Xây dựng web server với package net/http (15 phút)

  • Giới thiệu package net/http.

  • Khái niệm về HTTP request và response.

  • Cách tạo một HTTP server đơn giản.

  • Xử lý các HTTP route và HTTP method (GET, POST, PUT, DELETE, ...)

  • Thiết lập routing (điều hướng đường dẫn): ánh xạ các URL đến các hàm xử lý tương ứng.

2. Tạo Web Service (10 phút)

  • Định nghĩa Web Service (REST API)

  • Thiết kế các REST API endpoint cho ứng dụng danh bạ (thêm, sửa, xóa, tìm kiếm liên lạc)

  • Trả dữ liệu về dưới định dạng JSON.

3. Web client (5 phút)

  • Sử dụng package net/http để viết ứng dụng client gửi HTTP request tới web service.

  • Xử lý response từ web service.

4. Prometheus và Grafana (10 phút)

  • Giới thiệu Prometheus: Hệ thống giám sát nguồn mở (open-source monitoring system).

  • Giới thiệu Grafana: Công cụ trực quan hóa các chỉ số (metrics).

  • Thêm các metric đơn giản vào web service (ví dụ: đếm request, thời gian xử lý request).

  • Cài đặt Prometheus và Grafana (cài đặt đơn giản, có thể bằng Docker).

  • Tạo dashboard cơ bản trong Grafana để hiển thị các metric từ service.

5. Ứng dụng danh bạ - Web Service & Client (5 phút)

  • Chuyển đổi ứng dụng danh bạ thành web service với các endpoint REST API.

  • Viết một ứng dụng dòng lệnh (CLI) tương tác với web service này để quản lý danh bạ.

Bài tập:

  • Thêm tính năng xác thực (authentication) cơ bản cho web service.

  • Xử lý lỗi chi tiết hơn cho ứng dụng client.

  • Tìm hiểu cách triển khai web service lên môi trường thực tế (ví dụ dùng Nginx hoặc Docker).

Lưu ý:

  • Nếu có thể, sử dụng các kiến thức từ các buổi trước (JSON, concurrency) khi xây dựng web service để ôn tập lại.

  • Sự tích hợp với Prometheus và Grafana có thể được giữ cơ bản cho buổi này. Học viên quan tâm có thể tự tìm hiểu nâng cao thêm sau đó.

Buổi 9: Working with TCP/IP and WebSocket

Mục tiêu bài học:

  • Hiểu cách vận hành của các giao thức TCP/IP.

  • Làm việc với package net

  • Viết các ứng dụng client và server sử dụng TCP và UDP.

  • Hiểu WebSocket và cách ứng dụng.

Nội dung chi tiết (45 phút):

1. Giao thức TCP/IP (10 phút)

  • Giới thiệu mô hình TCP/IP (các tầng, khái niệm IP address, port).

  • Sự khác biệt cơ bản giữa giao thức TCP và UDP.

  • Ứng dụng phổ biến của TCP và UDP.

2. Package net trong Go (15 phút)

  • Cách tạo TCP listener và kết nối TCP bằng package net.

  • Gửi và nhận dữ liệu trên kết nối TCP.

  • Xử lý lỗi và đóng kết nối.

  • Tương tự, giới thiệu cách tạo UDP socket và truyền nhận dữ liệu qua UDP.

3. Ví dụ ứng dụng (10 phút)

  • TCP:

    • Viết một server 'echo' đơn giản (nhận dữ liệu từ client và gửi trả lại).

    • Viết một client tương ứng kết nối tới server này.

  • UDP:

    • Tạo server UDP lắng nghe và xử lý các gói tin.

    • Tạo client UDP gửi packet đến server.

4. WebSockets (10 phút)

  • Giới thiệu giao thức WebSocket: giao tiếp full-duplex, persistent trên nền TCP.

  • Các use case điển hình của WebSockets (chat, hiển thị thông tin real-time, ...).

  • Sử dụng thư viện của Go (ví dụ: gorilla/websocket) để tạo một WebSocket server đơn giản.

Bài tập:

  • Mở rộng server echo thành một server chat cho phép nhiều client kết nối.

  • Tạo ứng dụng client vẽ đồ thị thời gian thực bằng cách nhận dữ liệu cập nhật liên tục qua WebSocket.

Lưu ý:

  • Giải thích kỹ sự khác biệt khi làm việc với TCP (connection-oriented) và UDP (connectionless).

  • Demo các ứng dụng client-server, nhấn mạnh luồng thực thi và truyền dữ liệu.

  • Nếu còn thời gian, có thể giới thiệu về WebSockets nâng cao (ví dụ: channel, broadcast messages)

Buổi 10: Working with REST APIs

Mục tiêu bài học:

  • Hiểu rõ nguyên lý thiết kế REST API.

  • Xây dựng REST API server có tính đồng thời cao trong Go.

  • Tạo ứng dụng dòng lệnh (CLI) tương tác với các REST API bên ngoài.

  • Sử dụng Swagger để tạo tài liệu cho REST API.

  • Tìm hiểu cách upload và download file trong ứng dụng Go.

Nội dung chi tiết (45 phút):

1. Nguyên tắc REST API (10 phút)

  • Khái niệm REST (Representational State Transfer) và các nguyên tắc cốt lõi.

  • HTTP methods và cách map chúng với các hành động CRUD (Create, Read, Update, Delete).

  • Sử dụng HTTP status codes phù hợp để báo hiệu thành công/thất bại.

2. Xây dựng RESTful server đồng thời (15 phút)

  • Thiết kế các REST API endpoint cho một ứng dụng cụ thể (ví dụ: quản lý bài đăng blog).

  • Áp dụng các kiến thức từ buổi trước về web server, concurrency (goroutines, channels).

  • Lồng ghép database (ví dụ: PostgreSQL, MySQL) vào REST API server, thực hiện các thao tác cơ sở dữ liệu.

3. Ứng dụng dòng lệnh (CLI) để tương tác với REST API (5 phút)

  • Sử dụng package 'net/http' để xây dựng client gửi request đến REST API server (hoặc các service ngoài).

  • Sử dụng cobra hoặc các thư viện khác để tạo CLI với các lệnh tương ứng với các hành động API.

4. Swagger (10 phút)

  • Giới thiệu công cụ Swagger để tạo tài liệu cho REST API.

  • Hướng dẫn cách viết chú thích (annotation) đặc biệt trong Go code để tương thích với Swagger.

  • Dựng giao diện Swagger UI để trực quan hóa và thao tác với REST API.

5. Upload / Download file (5 phút)

  • Giới thiệu về MIME types.

  • Cách xử lý multipart form data để upload file trong Go.

  • Xử lý việc download file từ server (trả về file attachment).

Bài tập:

  • Thêm tính năng phân quyền cơ bản (authentication/authorization) vào REST API.

  • Mở rộng ứng dụng CLI để hỗ trợ các phương thức HTTP khác ngoài GET/POST.

  • Tìm hiểu cách tạo unit tests cho REST API server.

Lưu ý:

  • Chọn một use case rõ ràng, quy mô vừa phải trong ví dụ để buổi học tập trung, không bị quá rộng.

  • Nhắc lại các nguyên tắc và chuẩn về REST API trong quá trình phát triển.

  • Có thể dùng Postman hoặc các công cụ tương tự để test REST API song song với việc xây dựng CLI client của riêng mình.

Buổi 11: Code Testing and Profiling

Mục tiêu bài học:

  • Nắm chắc về cách viết unit tests, integration tests trong Go.

  • Kỹ thuật benchmark code Go.

  • Cách sử dụng profiler để phân tích hiệu năng ứng dụng.

  • Biết cách biên dịch chéo (cross-compilation).

  • Hiểu các công cụ hỗ trợ testing và tìm đoạn mã "dead code" (không thể chạy tới).

Nội dung chi tiết (45 phút):

1. Testing (20 phút)

  • Unit Tests:

    • Giới thiệu package testing: viết unit tests, coverage reports.

    • Các nguyên tắc viết unit test hiệu quả (tách biệt, mocks, table-driven tests, v.v.).

  • Integration Tests:

    • Khái niệm integration tests trong Go.

    • Cách kiểm thử tương tác giữa các components hoặc với hệ thống bên ngoài (database, services).

2. Benchmarking (10 phút)

  • Mục đích của việc benchmarking - đo lường hiệu năng code.

  • Cách sử dụng package testing để viết benchmark tests.

  • Phân tích kết quả benchmark và tìm điểm có thể tối ưu hóa.

3. Profiling (10 phút)

  • Giới thiệu profiler: phân tích chi tiết việc sử dụng CPU, bộ nhớ, v.v. của ứng dụng.

  • Sử dụng package net/http/pprof để lấy thông tin profiling.

  • Trực quan hóa dữ liệu profiling (ví dụ: sử dụng công cụ pprof hoặc graphviz).

4. Khác (5 phút)

  • Biên dịch chéo (cross-compilation): Tạo ứng dụng Go chạy được trên các nền tảng/kiến trúc hệ điều hành khác.

  • go:generate: Khái niệm và cách sử dụng.

  • Công cụ tìm dead code: (ví dụ go vet)

Bài tập:

  • Thực hành viết unit tests và integration tests cho các ứng dụng đã làm ở buổi trước (ví dụ: ứng dụng danh bạ, REST API).

  • Sử dụng Go profiler để phân tích đoạn code có vòng lặp/tính toán tốn kém.

  • Thực hành biên dịch chéo một ứng dụng Go đơn giản sang nền tảng khác (ví dụ: Linux -> Windows).

Lưu ý:

  • Dành phần lớn thời gian cho Unit Tests và sử dụng các ví dụ quen thuộc từ các bài trước đó để học viên nhanh chóng nắm bắt cách viết test.

  • Giải thích sự khác biệt giữa unit tests và integration tests.

Buổi 12: Working with gRPC

Mục tiêu bài học:

  • Hiểu bản chất và lợi ích của phương thức gRPC.

  • Định nghĩa service, methods và messages trong gRPC sử dụng Protocol Buffers (Protobuf).

  • Tạo server và client gRPC trong Go.

Nội dung chi tiết (45 phút):

1. Giới thiệu về gRPC (10 phút)

  • Khái niệm về gRPC: High-performance, language-neutral RPC framework.

  • Lợi ích của gRPC so với RESTful APIs (truyền tải dữ liệu hiệu quả hơn, gọi thủ tục từ xa - RPC).

  • So sánh với các phương thức giao tiếp khác (REST API, WebSockets).

2. Protocol Buffers (Protobuf) (15 phút)

  • Giới thiệu về Protocol Buffers: Ngôn ngữ mô tả cấu trúc dữ liệu trung gian (IDL - Interface Definition Language).

  • Định nghĩa các message (struct) và service (giao diện) sử dụng Protobuf.

  • Sử dụng công cụ protoc để biên dịch file .proto sang Go code.

3. Xây dựng gRPC server và client (20 phút)

  • Tạo service definition với các method trong file .proto (ví dụ: user service với các method GetUserCreateUser).

  • Biên dịch file .proto sang Go code (server-side và client-side).

  • Impl các method trên server-side.

  • Client-side: kết nối tới server, gọi các method từ xa và xử lý kết quả trả về.

Bài tập:

  • Thực hành xây dựng một gRPC service đơn giản (ví dụ: todo list application).

  • Nghiên cứu thêm về các tính năng nâng cao của gRPC (streaming, error handling).

Lưu ý:

  • Cung cấp sẵn các ví dụ đơn giản về Protobuf để học viên dễ hình dung.

  • Phân biệt rõ ràng giữa việc định nghĩa service trong Protobuf và việc implement các method trên server-side Go code.

  • Có thể giới thiệu thêm các công cụ hỗ trợ gRPC khác (gRPC gateway).

Buổi 13: Go Generics

Mục tiêu bài học

  • Hiểu rõ về tính năng Generics mới trong Go 1.18.

  • Cách viết các hàm và các kiểu dữ liệu generic.

  • Ứng dụng Generics để cải thiện tính tái sử dụng và type safety cho code Go.

Nội dung chi tiết (45 phút):

1. Giới thiệu về Generics (10 phút)

  • Khái niệm Generics: lập trình với các kiểu dữ liệu trừu tượng (ví dụ: viết hàm sort có thể sắp xếp cho cả danh sách số nguyên, danh sách chuỗi, v.v).

  • Lợi ích của Generics: Tăng tính tái sử dụng, type safety.

  • Cú pháp mới cho generics trong Go 1.18: type parameters, constraints.

2. Sử dụng Generics (20 phút)

  • Hàm Generic:

    • Viết hàm generic cơ bản (ví dụ: Min, Max).

    • Sử dụng type parameters và constraints để giới hạn các kiểu dữ liệu đầu vào.

  • Kiểu dữ liệu Generic:

    • Định nghĩa struct và interface có type parameters.

    • Thực hành tạo ra các kiểu dữ liệu generic điển hình (linked list, stack, ...).

3. Ứng dụng thực tế của Generics (10 phút)

  • Cải thiện các thành phần viết ở buổi trước bằng cách áp dụng Generics khi có thể (ví dụ: viết lại data store cho ứng dụng danh bạ có thể lưu trữ được nhiều kiểu dữ liệu khác nhau).

  • Thảo luận về một số hàm và kiểu dữ liệu tiêu chuẩn trong Go có thể sử dụng Generics để mở rộng (ví dụ sort)

4. Hạn chế của Generics trong Go (5 phút)

  • Hiệu năng tiềm ẩn (overhead) do Generics gây ra

  • Giới hạn trong quá trình chuyển đổi, các trường hợp phức tạp, v.v.

Bài tập:

  • Viết một hàm Filter generic: áp dụng điều kiện cho các phần tử trong một slice với kiểu dữ liệu bất kỳ, trả về slice mới thỏa mãn.

  • Tạo kiểu dữ liệu binary tree generic.

  • Tìm các thư viện hoặc đoạn code có thể được cải thiện bằng cách sử dụng Generics.

Lưu ý:

  • Bắt đầu với các ví dụ đơn giản, cụ thể để làm rõ cú pháp và khái niệm của Generics.

  • Khuyến khích học viên tự tạo hoặc sửa đổi code cho quen dần với Generics.

Buổi 14: Go Garbage Collector

Mục tiêu bài học:

  • Hiểu cách thức hoạt động của Garbage Collector (GC) trong Go.

  • Xác định những yếu tố tác động đến hiệu suất của ứng dụng Go do GC gây ra.

  • Tối ưu hóa code để giảm áp lực cho

Nội dung chi tiết:

1. Giới thiệu về Garbage Collector trong Go (10 phút)

  • Khái niệm: Cơ chế tự động giải phóng vùng nhớ không còn sử dụng.

  • Phân biệt với quản lý bộ nhớ thủ công (manual memory management) như trong C/C++.

  • Các thuật toán Garbage Collection nói chung (reference counting, tracing GC).

  • Go sử dụng Tracing Garbage Collector.

2. Hoạt động của Tracing Garbage Collector (15 phút)

  • Các giai đoạn:

    • Marking: Đánh dấu các object đang được sử dụng bắt đầu từ root objects.

    • Sweeping: Giải phóng vùng nhớ của objects không được đánh dấu.

  • Stop-the-world (STW): GC tạm dừng chương trình để thực hiện việc thu gom.

  • Tricolor mark-and-sweep algorithm của Go.

3. Ảnh hưởng của GC tới hiệu suất (15 phút)

  • GC overhead: Thời gian thực thi của GC chiếm tỉ lệ trong tổng thời gian chạy của chương trình.

  • GC pauses: Các lần tạm dừng chương trình do GC gây ra.

  • Mối quan hệ giữa tần suất GC và độ dài GC pauses.

  • Cách sử dụng runtime metrics và pprof để theo dõi GC trong ứng dụng Go.

4. Tối ưu hóa cho GC (5 phút)

  • Các kỹ thuật giúp giảm tải cho GC:

    • Tái sử dụng object

    • Tránh tạo nhiều object tạm thời

    • Sử dụng sync.Pool cho một số trường hợp

    • Cân nhắc điều chỉnh các tham số cho GC (GOGC)

Bài tập:

  • Dùng pprof để phân tích một ứng dụng Go đơn giản, trực quan hóa hoạt động của GC.

  • Tìm hiểu cách điều chỉnh tham số GC (GOGC) và thực hành đo lường sự ảnh hưởng.

  • Thảo luận về trade-offs giữa tối ưu cho GC và độ phức tạp của code.

Lưu ý:

  • Sử dụng hình ảnh, diagram để trình bày, làm rõ các giai đoạn của GC.

  • Việc tối ưu hóa GC phải được cân bằng với việc duy trì và phát triển code dễ hiểu và đúng (correct) .

Buổi 15: Một số thuật toán thường gặp

Mục tiêu:

  • Nắm vững một số thuật toán cơ bản và phổ biến trong lập trình Go.

  • Luyện tập áp dụng các thuật toán vào giải quyết bài toán thực tế.

  • Nâng cao kỹ năng tư duy logic và lập trình hiệu quả.

Nội dung:

  1. Giới thiệu (10 phút)

    • Vai trò và tầm quan trọng của thuật toán trong lập trình.

    • Phân loại các loại thuật toán thường gặp.

    • Độ phức tạp và cách đo lường độ phức tạp của thuật toán.

  2. Thuật toán Tìm kiếm (20 phút)

    • Tìm kiếm tuyến tính (Linear Search)

    • Tìm kiếm nhị phân (Binary Search)

    • Bảng băm (Hash Table) và thuật toán băm (Hashing)

  3. Thuật toán Sắp xếp (20 phút)

    • Sắp xếp bọt (Bubble Sort)

    • Sắp xếp chọn (Selection Sort)

    • Sắp xếp chèn (Insertion Sort)

    • Sắp xếp nhanh (Quick Sort)

    • Sắp xếp gộp (Merge Sort)

  4. Thuật toán Xâu ký tự (10 phút)

    • So sánh chuỗi

    • Tìm kiếm chuỗi con

    • Thay thế và xóa ký tự trong chuỗi

  5. Ứng dụng thực tế (5 phút)

    • Giải quyết bài toán tìm kiếm trong danh sách dữ liệu.

    • Sắp xếp danh sách sinh viên theo điểm thi.

    • Xử lý văn bản: tìm kiếm từ khóa, đếm số từ, v.v.

Luyện tập:

  • Viết code thực hiện các thuật toán tìm kiếm, sắp xếp, xử lý chuỗi cơ bản.

  • Giải quyết bài toán thực tế bằng cách áp dụng các thuật toán đã học.

  • Thảo luận về hiệu quả và tính ứng dụng của các thuật toán khác nhau.