Showing posts with label Flutter. Show all posts
Showing posts with label Flutter. Show all posts

Cơ sở dữ liệu thời gian thực cho ứng dụng Flutter

Cơ Sở dữ liệu thời gian thực trong Flutter: Làm chủ Firebase Realtime Database

Trong kỷ nguyên ứng dụng di động hiện nay, tính năng "thời gian thực" (real-time) không còn là một lựa chọn mà đã trở thành tiêu chuẩn. Cho dù bạn đang xây dựng một ứng dụng chat, một hệ thống theo dõi đơn hàng hay bảng điều khiển chứng khoán, việc dữ liệu được cập nhật ngay lập tức mà không cần tải lại trang là vô cùng quan trọng. Trong bài viết này, chúng ta sẽ cùng tìm hiểu cách tích hợp Firebase Realtime Database vào Flutter một cách chi tiết và dễ hiểu nhất.

Cơ Sở dữ liệu thời gian thực trong Flutter: Làm chủ Firebase Realtime Database


1. Firebase Realtime Database là gì?

Firebase Realtime Database là một cơ sở dữ liệu NoSQL được lưu trữ trên đám mây. Khác với các cơ sở dữ liệu truyền thống sử dụng các truy vấn HTTP, Firebase sử dụng WebSockets để đồng bộ hóa dữ liệu giữa tất cả các thiết bị khách (clients) trong thời gian thực.

Dữ liệu trong Firebase được lưu trữ dưới dạng một cây JSON khổng lồ. Khi có bất kỳ thay đổi nào xảy ra tại một node dữ liệu, mọi thiết bị đang kết nối tới node đó sẽ nhận được cập nhật chỉ trong vài mili giây.

2. Tại sao nên chọn Firebase cho dự án Flutter?

Flutter và Firebase đều là "con cưng" của Google, do đó sự tương thích giữa chúng gần như là hoàn hảo. Dưới đây là những lý do bạn nên sử dụng cặp bài trùng này:

  • Tốc độ phát triển: Bạn không cần phải xây dựng Backend phức tạp. Firebase cung cấp sẵn mọi thứ.
  • Khả năng ngoại tuyến: Ứng dụng vẫn hoạt động khi mất mạng và tự động đồng bộ khi có kết nối trở lại.
  • Miễn phí bắt đầu: Gói Spark của Firebase rất hào phóng cho các dự án nhỏ và cá nhân.

3. Các bước chuẩn bị và cài đặt

Để bắt đầu, bạn cần thực hiện các bước cấu hình cơ bản sau:

Bước 1: Tạo dự án trên Firebase Console

Truy cập Firebase Console, tạo một dự án mới và thêm ứng dụng Android/iOS của bạn vào.

Bước 2: Thêm thư viện vào Flutter

Mở file pubspec.yaml và thêm các dependencies cần thiết:

dependencies:
  flutter:
    sdk: flutter
  firebase_core: ^latest_version
  firebase_database: ^latest_version

Sau đó chạy lệnh flutter pub get để tải thư viện về.

4. Thao tác với dữ liệu (CRUD Operations)

Trong Flutter, để thao tác với Firebase Realtime Database, chúng ta sử dụng class DatabaseReference.

Ghi dữ liệu (Create/Update)

Để lưu một thông tin mới, ví dụ như tên người dùng:

final ref = FirebaseDatabase.instance.ref("users/123");
await ref.set({
  "name": "Thanh Tran",
  "email": "thanhtran@example.com",
  "age": 25
});

Đọc dữ liệu một lần (Read)

Nếu bạn chỉ muốn lấy dữ liệu một lần duy nhất mà không cần lắng nghe thay đổi:

final snapshot = await ref.child('name').get();
if (snapshot.exists) {
    print(snapshot.value);
}

5. Lắng nghe dữ liệu thời gian thực với StreamBuilder

Đây là phần quan trọng nhất giúp ứng dụng Flutter của bạn trở nên "sống động". StreamBuilder sẽ tự động xây dựng lại giao diện mỗi khi dữ liệu trên Firebase thay đổi.

StreamBuilder(
  stream: FirebaseDatabase.instance.ref("messages").onValue,
  builder: (context, AsyncSnapshot<DatabaseEvent> snapshot) {
    if (snapshot.hasData && !snapshot.hasError) {
      final data = snapshot.data!.snapshot.value as Map?;
      if (data == null) return Text("Không có dữ liệu");
      
      return ListView(
        children: data.values.map((v) => ListTile(title: Text(v['text']))).toList(),
      );
    }
    return CircularProgressIndicator();
  },
)
Mẹo nhỏ: Luôn kiểm tra snapshot.hasData để tránh lỗi hiển thị khi dữ liệu đang được tải hoặc bị trống.

6. Một số lưu ý về bảo mật và tối ưu chi phí

Firebase Realtime Database tính phí dựa trên lưu lượng băng thôngdung lượng lưu trữ. Để tránh những hóa đơn bất ngờ, bạn cần lưu ý:

  • Quy tắc bảo mật (Security Rules): Đừng bao giờ để quy tắc ở chế độ .read: true, .write: true cho mọi người. Hãy thiết lập để chỉ người dùng đã đăng nhập mới có quyền truy cập.
  • Cấu trúc dữ liệu phẳng: Tránh lồng các object quá sâu. Nếu bạn tải một node cha, Firebase sẽ tải về toàn bộ các node con bên trong nó, gây lãng phí băng thông.
  • Sử dụng Index: Thiết lập index cho các trường thường xuyên dùng để tìm kiếm (query) để tăng hiệu suất.

7. Kết luận

Việc kết hợp Firebase Realtime Database với Flutter mở ra khả năng sáng tạo không giới hạn cho các lập trình viên. Từ những ứng dụng đơn giản đến những hệ thống phức tạp, khả năng đồng bộ dữ liệu tức thời sẽ mang lại trải nghiệm người dùng tuyệt vời nhất.

Hy vọng bài viết này đã giúp bạn có cái nhìn tổng quan và bắt đầu những dòng code đầu tiên với Firebase. Đừng quên theo dõi blog để cập nhật thêm các kiến thức hữu ích về lập trình di động nhé!


Biên soạn: Thanh Tran
Nguồn tham khảo: Firebase Documentation & Flutter Community.

Giới thiệu REST API trong FLUTTER

Hướng dẫn căn bản: Cách tích hợp REST API  trong Flutter

Trong quá trình học và phát triển ứng dụng di động với Flutter, bạn sẽ nhận ra rằng một ứng dụng không thể chỉ hoạt động với dữ liệu tĩnh trên máy. Để ứng dụng "sống" và liên tục cập nhật thông tin (như đọc báo, xem danh sách sản phẩm, hiển thị thời tiết), bạn cần phải kết nối nó với máy chủ (server). Và cầu nối phổ biến nhất để làm việc này chính là REST API.

Hướng dẫn căn bản: Cách tích hợp REST API  trong Flutter


Bài viết này sẽ giải thích cho bạn REST API là gì theo ngôn ngữ đơn giản nhất, cũng như hướng dẫn chi tiết từng bước cách gọi một API trong Flutter để hiển thị dữ liệu lên màn hình. Hãy cùng bắt đầu nhé!



1. REST API là gì? Hiểu sao cho đơn giản?

Hãy tưởng tượng bạn đang vào một nhà hàng. Bạn (Ứng dụng Flutter - Client) muốn gọi món ăn. Nhà bếp (Máy chủ - Server) là nơi có nguyên liệu và chế biến món ăn. Tuy nhiên, bạn không thể tự chạy vào bếp lấy đồ ăn được. Bạn cần một người Bồi bàn (API) để ghi lại yêu cầu của bạn, mang vào bếp, và sau đó bưng món ăn từ bếp ra bàn cho bạn.

REST API (Representational State Transfer Application Programming Interface) chính là "người bồi bàn" đó trên môi trường internet. Nó tuân theo một bộ quy tắc nhất định để Client và Server có thể nói chuyện được với nhau.

Trong REST API, chúng ta có 4 hành động (phương thức) cơ bản tương ứng với chuẩn CRUD (Create, Read, Update, Delete):

  • GET (Read): Lấy dữ liệu từ server về (Ví dụ: Lấy danh sách sản phẩm).
  • POST (Create): Gửi dữ liệu mới lên server (Ví dụ: Tạo tài khoản mới, Gửi bình luận).
  • PUT / PATCH (Update): Cập nhật dữ liệu đã có trên server.
  • DELETE (Delete): Xóa dữ liệu trên server.

Dữ liệu trao đổi qua lại thường được định dạng dưới dạng JSON (JavaScript Object Notation) - một định dạng văn bản rất dễ đọc cho cả người và máy.

2. Tại sao ứng dụng Flutter của bạn lại cần API?

Sử dụng API mang lại những lợi ích khổng lồ cho ứng dụng di động:

  • Dữ liệu luôn mới: Bạn không cần bắt người dùng cập nhật ứng dụng trên App Store chỉ để đổi một dòng chữ hay thêm một sản phẩm. Mọi thứ được tải từ server xuống theo thời gian thực.
  • Tiết kiệm dung lượng: Ứng dụng sẽ rất nhẹ vì dữ liệu (hình ảnh, văn bản, video) nằm ở server, ứng dụng chỉ tải về những thứ cần thiết khi người dùng lướt tới.
  • Đồng bộ đa nền tảng: Bạn có thể dùng chung một REST API cho cả ứng dụng Flutter (iOS/Android), ứng dụng Web và ứng dụng Desktop. Đảm bảo mọi nền tảng đều thấy cùng một dữ liệu.

3. Ví dụ minh họa: Gọi API hiển thị danh sách bài viết

Trong ví dụ này, chúng ta sẽ sử dụng một Fake API miễn phí dành cho lập trình viên là JSONPlaceholder để lấy về một danh sách các bài viết (Posts) bằng phương thức GET.

Đường dẫn API: https://jsonplaceholder.typicode.com/posts

Bước 1: Cài đặt gói thư viện HTTP

Flutter mặc định không có sẵn công cụ tối ưu để gọi API, nên chúng ta sẽ sử dụng một thư viện (package) rất phổ biến của Google là http.

Mở file pubspec.yaml trong project của bạn và thêm dòng sau vào dưới mục dependencies:

dependencies:
  flutter:
    sdk: flutter
  http: ^1.1.0 # Thêm thư viện http tại đây

Sau đó chạy lệnh flutter pub get trong terminal để tải thư viện về.

Bước 2: Tạo Lớp Dữ Liệu (Model)

Khi gọi API, dữ liệu trả về là một chuỗi JSON (text). Để Flutter có thể hiểu và dễ dàng lấy ra các thông tin (như tiêu đề, nội dung), chúng ta cần chuyển đổi chuỗi JSON đó thành một đối tượng Dart. Ở đây ta tạo một class Post.

class Post {
  final int id;
  final String title;
  final String body;

  Post({required this.id, required this.title, required this.body});

  // Hàm chuyển đổi từ JSON (Map) sang Object Dart
  factory Post.fromJson(Map<String, dynamic> json) {
    return Post(
      id: json['id'],
      title: json['title'],
      body: json['body'],
    );
  }
}

Bước 3: Viết hàm bất đồng bộ để gọi API (Fetch Data)

Việc kết nối mạng sẽ tốn thời gian (có thể nhanh hoặc chậm tùy mạng). Do đó, chúng ta phải sử dụng hàm bất đồng bộ (Future, async, await) để ứng dụng không bị đơ trong lúc chờ đợi server phản hồi.

import 'dart:convert';
import 'package:http/http.dart' as http;

Future<List<Post>> fetchPosts() async {
  // Gửi request GET tới server
  final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'));

  // Kiểm tra mã trạng thái (StatusCode 200 nghĩa là thành công)
  if (response.statusCode == 200) {
    // Ép kiểu dữ liệu chuỗi trả về sang dạng List
    List jsonResponse = jsonDecode(response.body);
    // Chuyển đổi List JSON sang List<Post>
    return jsonResponse.map((data) => Post.fromJson(data)).toList();
  } else {
    // Nếu lỗi, ném ra một ngoại lệ
    throw Exception('Không thể tải danh sách bài viết');
  }
}

Bước 4: Hiển thị dữ liệu lên giao diện với FutureBuilder

Để vẽ giao diện dựa trên dữ liệu đang tải từ mạng, Flutter cung cấp một Widget tuyệt vời có tên là FutureBuilder. Nó sẽ tự động cập nhật UI tùy theo trạng thái: Đang tải, Tải lỗi, hoặc Tải thành công.

import 'package:flutter/material.dart';

class PostListScreen extends StatefulWidget {
  @override
  _PostListScreenState createState() => _PostListScreenState();
}

class _PostListScreenState extends State<PostListScreen> {
  late Future<List<Post>> futurePosts;

  @override
  void initState() {
    super.initState();
    // Gọi hàm fetch data ngay khi màn hình khởi tạo
    futurePosts = fetchPosts();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Danh Sách Bài Viết API')),
      body: FutureBuilder<List<Post>>(
        future: futurePosts,
        builder: (context, snapshot) {
          // Trạng thái 1: Đang tải dữ liệu
          if (snapshot.connectionState == ConnectionState.waiting) {
            return Center(child: CircularProgressIndicator());
          } 
          // Trạng thái 2: Có lỗi xảy ra
          else if (snapshot.hasError) {
            return Center(child: Text('Lỗi: ${snapshot.error}'));
          } 
          // Trạng thái 3: Tải thành công và có dữ liệu
          else if (snapshot.hasData) {
            List<Post> posts = snapshot.data!;
            return ListView.builder(
              itemCount: posts.length,
              itemBuilder: (context, index) {
                return Card(
                  margin: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
                  child: ListTile(
                    leading: CircleAvatar(child: Text(posts[index].id.toString())),
                    title: Text(posts[index].title, style: TextStyle(fontWeight: FontWeight.bold)),
                    subtitle: Text(posts[index].body, maxLines: 2, overflow: TextOverflow.ellipsis),
                  ),
                );
              },
            );
          }
          // Trạng thái mặc định
          return Center(child: Text('Không có dữ liệu'));
        },
      ),
    );
  }
}

4. Những lưu ý quan trọng khi làm việc với API

Để ứng dụng của bạn trở nên chuyên nghiệp và ít gặp lỗi (bug) khi người dùng sử dụng, bạn cần chú ý những điểm sau khi làm việc với REST API:

  • Xử lý lỗi (Error Handling): Không phải lúc nào server cũng trả về kết quả thành công (Mã 200). Đôi khi mất mạng, đôi khi link API bị sai (Mã 404), hoặc lỗi từ server (Mã 500). Bạn phải luôn có khối lệnh try-catch hoặc xử lý statusCode cẩn thận để ứng dụng không bị văng (crash) bất ngờ.
  • Parsing JSON cẩn thận: Kiểu dữ liệu từ API trả về có thể thay đổi (ví dụ API hứa trả về một chuỗi String nhưng lại trả về null). Bạn nên kiểm tra null an toàn (Null Safety) khi chuyển đổi JSON. Các lập trình viên thường dùng thư viện như json_serializable hoặc freezed để tự động hóa và làm an toàn quá trình này thay vì tự viết tay.
  • Quản lý trạng thái (State Management): Trong các ứng dụng thực tế lớn, thay vì dùng setState hay FutureBuilder ở mọi nơi, người ta sẽ kết hợp gọi API với các công cụ quản lý trạng thái như Provider, Riverpod, BLoC hoặc GetX để cấu trúc code gọn gàng, tách biệt phần Giao diện (UI) và phần Xử lý dữ liệu (Logic) ra khỏi nhau.

5. Lời kết

Kết nối REST API trong Flutter ban đầu có thể trông hơi phức tạp vì có liên quan đến các khái niệm bất đồng bộ (async/await) và chuyển đổi JSON. Tuy nhiên, khi bạn đã làm quen với mô hình cơ bản (Tạo Model -> Viết hàm gọi HTTP -> Dùng FutureBuilder hiển thị), bạn sẽ thấy nó cực kỳ logic và mạnh mẽ.

Hi vọng bài viết này đã giúp bạn hiểu rõ bản chất của API và tự tin triển khai thành công tính năng này vào ứng dụng Flutter của mình. Hãy thử thay đổi đường dẫn API trong ví dụ trên bằng một API thời tiết hay giá coin để thấy sự thú vị nhé. Chúc các bạn code vui vẻ!

Hướng dẫn tự học lập trình Flutter với Dart trên Android Sutudio

1. Tổng quan về Flutter

Flutter là một bộ công cụ giao diện người dùng (UI framework) mã nguồn mở do Google tạo ra và ra mắt vào năm 2017. Điểm "ăn tiền" lớn nhất của Flutter là khả năng phát triển ứng dụng đa nền tảng (Cross-platform) chỉ với một mã nguồn (single codebase).

Thay vì phải học Java/Kotlin để viết app cho Android, rồi lại phải học Swift/Objective-C để viết app cho iOS, bạn chỉ cần học Flutter là có thể build app chạy mượt mà trên cả 2 hệ điều hành này,. Hiện nay, Flutter còn hỗ trợ build ra cả Web và các ứng dụng Desktop (Windows, macOS, Linux).

Flutter không sử dụng các thành phần giao diện mặc định của hệ điều hành mà tự vẽ lại mọi pixel trên màn hình bằng engine đồ họa riêng (Skia/Impeller), giúp ứng dụng có hiệu năng cực kỳ ấn tượng (có thể đạt 60-120fps) và giao diện nhất quán trên mọi thiết bị,. Rất nhiều ông lớn đang sử dụng Flutter như: chính Google (Google Pay), Alibaba, BMW, Toyota, v.v.,.

Hướng dẫn tự học lập trình Flutter với Dart trên Android Sutudio
Hướng dẫn tự học lập trình Flutter với Dart trên Android Sutudio (nguồn NotebookLM)


2. Giới thiệu ngôn ngữ lập trình Dart

Để học Flutter, bạn bắt buộc phải làm quen với ngôn ngữ lập trình Dart. Đây cũng là một ngôn ngữ do Google phát triển, được tối ưu hóa riêng cho việc xây dựng giao diện người dùng.

Nếu bạn đã từng học C++, C# hay Java ở trường đại học, bạn sẽ thấy Dart cực kỳ "quen mặt". Dart là ngôn ngữ kiểu tĩnh (statically typed), hỗ trợ lập trình hướng đối tượng (OOP) hoàn chỉnh với các khái niệm quen thuộc như Class, Interface, Mixin, Kế thừa....

Một số điểm thú vị của Dart khi kết hợp với Flutter:

  • Hot Reload: Dart hỗ trợ biên dịch Just-In-Time (JIT) trong quá trình phát triển. Điều này cho phép tính năng "Hot Reload" hoạt động – bạn vừa sửa code, lưu lại là giao diện app trên điện thoại cập nhật ngay lập tức trong chưa tới 1 giây mà không cần khởi động lại app,.
  • Null Safety: Dart áp dụng cơ chế an toàn null (Sound Null Safety), giúp bạn tránh được lỗi "NullPointerException" khét tiếng, làm cho code an toàn và ít lỗi vặt hơn,.

3. Các bước cài đặt Flutter trên Android Studio

Để lập trình Flutter, bạn cần cài đặt Flutter SDK và một IDE (môi trường lập trình). Android Studio hoặc Visual Studio Code là 2 lựa chọn phổ biến nhất,. Ở đây, chúng ta sẽ dùng Android Studio vì nó tích hợp sẵn các công cụ máy ảo rất tiện lợi.

Bước 1: Tải và cài đặt Flutter SDK

  • Truy cập link tải chính thức: Tải Flutter SDK.
  • Tải file .zip dành cho Windows (hoặc macOS/Linux tùy máy bạn).
  • Giải nén thư mục (Lưu ý: Không nên để trong C:\Program Files, hãy để ở nơi dễ truy cập như C:\src\flutter).
  • Cấu hình biến môi trường (PATH): Mở Environment Variables trên Windows, tìm biến Path, thêm đường dẫn C:\src\flutter\bin vào để máy tính nhận diện được lệnh flutter.

Bước 2: Tải và cài đặt Android Studio

  • Truy cập link tải: Tải Android Studio.
  • Cài đặt bình thường (cứ bấm Next và chọn Standard Installation). Đảm bảo Android SDK và Android Emulator được tick chọn để cài đặt.

Bước 3: Cài đặt Plugin Flutter trong Android Studio

  • Mở Android Studio lên.
  • Vào mục Plugins (hoặc File -> Settings -> Plugins),.
  • Tìm kiếm từ khóa Flutter và nhấn Install. Nó sẽ yêu cầu bạn cài thêm plugin Dart, bạn cứ chọn đồng ý.
  • Khởi động lại (Restart) Android Studio.

Bước 4: Kiểm tra cài đặt

  • Mở Command Prompt (CMD) hoặc Terminal, gõ lệnh: flutter doctor,.
  • Công cụ này sẽ kiểm tra xem bạn còn thiếu gì không. Nếu thấy tất cả đều có dấu tích xanh [✓], xin chúc mừng, bạn đã cài đặt thành công!. (Nếu có lỗi yêu cầu chấp nhận Android License, chỉ cần gõ flutter doctor --android-licenses và bấm 'y' cho đến hết,).

4. Các bước tạo và chạy 1 ứng dụng đầu tiên

Bây giờ chúng ta sẽ làm ứng dụng "Hello World" huyền thoại nhé:

Bước 1: Tạo project

  • Mở Android Studio, chọn New Flutter Project,.
  • Đảm bảo đường dẫn "Flutter SDK path" trỏ đúng vào thư mục Flutter bạn đã giải nén (VD: C:\src\flutter).
  • Đặt tên project (lưu ý viết chữ thường và dùng dấu gạch dưới, ví dụ: hello_flutter), sau đó nhấn Finish,.

Bước 2: Xóa code mẫu và viết code mới Flutter sẽ tự sinh ra một thư mục project. Hãy nhớ nguyên tắc: 90% thời gian code của bạn sẽ nằm trong thư mục lib/. Mở file lib/main.dart, xóa hết toàn bộ code có sẵn đi và chép đoạn code cực kỳ đơn giản sau đây vào:

import 'package:flutter/material.dart';

// Hàm main là nơi chương trình bắt đầu chạy
void main() {
  runApp(const MyApp());
}

// Tạo một Widget cơ bản
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Scaffold(
        body: Center(
          child: Text(
            'Hello World - Chào sinh viên IT!',
            style: TextStyle(fontSize: 24, color: Colors.blue),
          ),
        ),
      ),
    );
  }
}

Giải thích code nhanh: Mọi thứ trong Flutter đều là Widget (thành phần giao diện). MaterialApp là khung chứa app, Scaffold cung cấp cấu trúc màn hình cơ bản, Center giúp căn giữa nội dung, và Text dùng để hiển thị chữ.

Bước 3: Chạy ứng dụng

  • Bạn có thể cắm điện thoại thật vào máy tính (nhớ bật USB Debugging) hoặc chọn một máy ảo (Emulator) ngay trên thanh công cụ của Android Studio hoặc chạy trực tiếp trên trình duyệt Chrome,.
  • Nhấn nút Run (biểu tượng hình tam giác màu xanh),.
  • Đợi một lát để code biên dịch, và Bùm! Dòng chữ "Hello World" đã hiện lên màn hình điện thoại của bạn.

5. Một số tài liệu tham khảo hữu ích

Để tự học Flutter ở mức cơ bản đến nâng cao, bạn có thể lưu lại các trang web "gối đầu giường" sau:

  1. Trang chủ Flutter (Tiếng Anh): Nơi chứa mọi tài liệu chính thống, chính xác nhất từ Google.
  2. Trang chủ ngôn ngữ Dart (Tiếng Anh): Giúp bạn tra cứu cú pháp và cách hoạt động của Dart.
  3. DartPad (Lập trình trực tuyến): Nếu máy yếu chưa kịp cài đặt IDE, bạn có thể lên đây gõ code Dart/Flutter và xem kết quả ngay trên trình duyệt web.
  4. Học qua series bài viết tiếng Việt (Viblo / Cafedev / 200Lab): Rất nhiều lập trình viên Việt Nam chia sẻ các bài hướng dẫn chi tiết từ biến, hàm cho đến cách chia bố cục màn hình.
  5. Kho mã nguồn mở (Pub.dev): Khi bạn cần dùng thư viện bên ngoài (như gọi API, lưu dữ liệu), hãy lên đây tìm kiếm.

Chúc các bạn sinh viên IT có những giờ phút "code dạo" thật thú vị và sớm hoàn thành được những chiếc app xịn xò của riêng mình nhé!

Nếu bạn muốn có nguồn thu tự động, hoàn toàn miễn phí và vô cùng đơn giản thì có thể tham khảo app kiếm tiền Honeygain và EarnApp tại đây.

Nguồn NotebookLM

Categories

AI (13) AI programming (1) ASP (1) Android (32) App Honeygain (5) Assembly (17) Biểu diễn thuật toán (1) Bubble-Sort (1) Bài giảng (2) Bài giảng lập trình C và Cpp (21) Bài viết hay (109) Bản đồ tư duy (1) C Plus Plus (103) C/C++ (16) CDSL phân tán (1) CSS (2) Cơ sở dữ liệu (11) Danh ngôn lập trình (1) Datamining (4) Genetic Algorithm (1) Giáo trình (2) Giải thuật tiến hóa - thuật toán di truyền (2) Google App Engine (2) Góc học tập (34) HTML (1) Hướng dẫn kiếm tiền online tại nhà (7) Hướng dẫn sử dụng Emu8086 (1) Học lập trình (131) Học lập trình C và CPP qua ví dụ (17) Java (54) Java Căn bản (6) JavaScript (5) Kỹ năng đọc hiệu quả (1) Kỹ thuật lập trình (16) Kỹ thuật đồ họa máy tính (10) Lý thuyết Cơ sở dữ liệu (2) Lý thuyết đồ thị (11) Lập trình Cơ sở dữ liệu (2) Lập trình Python (2) Lập trình căn bản (8) Lập trình hướng đối tượng với Java (7) Lập trình mobile (9) Lập trình mạng (6) Lập trình nhúng (1) Lập trình trí tuệ nhân tạo (2) ML (1) MMO (7) MS Access (1) Machine learning (2) Mạng máy tính (1) Mẹo tìm kiếm trên Google (1) Nghiên cứu khoa học (3) Ngôn ngữ lập trình (2) Những cuốn sách hay mà bạn nên đọc khi còn trẻ (1) Pascal (3) Phương pháp tính toán tối ưu (2) Phương pháp tối ưu (2) Quản lý dự án CNTT (1) SEO (1) SQL (5) Swift (9) Sách hay (4) Thiết kế Web (2) Thuật toán (51) Thuật toán Sắp Xếp -Sort (9) Thuật toán Tìm kiếm - Search (5) Thuật toán di truyền (4) Thực hành Android (2) Tin học văn phòng (5) Tiện ích máy tính (3) Toán rời rạc (13) Treo máy kiếm tiền (3) Trí tuệ nhân tạo (18) Tài liệu tham khảo (5) Tìm hiểu Blockchain (2) Tự học Android (3) Tự học Android qua ví dụ (1) Tự học JavaScript (1) Tự học lập trình (9) Tự học lập trình Android (17) Tự học lập trình C và CPP (14) Tự học lập trình java qua các ví dụ (8) XML (1) blockchain (2) bài giảng quản lý dự án CNTT (1) bài tập java (3) bài tập lập trình (4) cấu trúc dữ liệu giải thuật (15) hướng dẫn viết báo (1) học lập trình Java (11) học máy (5) hợp ngữ (8) lập trình viên (3) phưng pháp đơn hình (2) thuật toán AI (2) tài liệu CNTT miễn phí (4) tính toán tối ưu (1) tự học lập trình iOS (8) tự học lập trình python (1) ví dụ Assembly (1) Đại số gia tử và ứng dụng (1) Đồ họa (4)