Back to blog

Giai đoạn 1: Nền tảng Java - Bắt đầu với Java

javaprogrammingfundamentalsbeginnerbackend
Giai đoạn 1: Nền tảng Java - Bắt đầu với Java

Chào mừng đến với Giai đoạn 1

Chào mừng bạn đến với giai đoạn đầu tiên trong hành trình học Java! Nếu bạn đang chuyển từ một ngôn ngữ lập trình khác, bạn sẽ tìm thấy nhiều khái niệm quen thuộc ở đây. Mục tiêu của giai đoạn này là giúp bạn làm quen với cú pháp Java và hiểu cách Java tiếp cận các khái niệm lập trình cơ bản.

Đây không phải là một hướng dẫn "biến là gì?". Thay vào đó, chúng ta sẽ tập trung vào cú pháp, quy ước và mẫu đặc trùng của Java để phân biệt nó với các ngôn ngữ khác mà bạn có thể biết.

Thời gian cam kết: 2 tuần, 1-2 giờ mỗi ngày
Điều kiện tiên quyết: Kinh nghiệm lập trình với bất kỳ ngôn ngữ nào

Bạn sẽ học được gì

Đến cuối Giai đoạn 1, bạn sẽ có thể:

✅ Thiết lập môi trường phát triển Java
✅ Viết và chạy các chương trình Java
✅ Hiểu hệ thống kiểu của Java
✅ Sử dụng các cấu trúc điều khiển luồng hiệu quả
✅ Viết các phương thức với chữ ký phù hợp
✅ Làm việc với mảng và chuỗi
✅ Tạo các lớp và đối tượng cơ bản
✅ Hiểu mô hình biên dịch và thực thi của Java

Thiết lập môi trường của bạn

1. Cài đặt JDK

Tải xuống và cài đặt Java Development Kit (JDK):

Khuyến nghị: Java 17 LTS hoặc Java 21 LTS

Các lựa chọn:

  • Oracle JDK (chính thức, yêu cầu đăng ký)
  • OpenJDK (mã nguồn mở, chức năng giống hệt)
  • Amazon Corretto (bản phân phối được AWS hỗ trợ)

Xác minh cài đặt:

java --version
javac --version

Cả hai lệnh đều hiển thị phiên bản 17+ hoặc 21+.

2. Chọn một IDE

IntelliJ IDEA (Khuyến nghị):

  • Tải xuống: IntelliJ IDEA Community Edition
  • Hỗ trợ Java tốt nhất, hoàn thành mã thông minh
  • Phiên bản Community miễn phí rất tuyệt vời

Các lựa chọn thay thế:

  • Eclipse - Trưởng thành, miễn phí và được sử dụng rộng rãi
  • VS Code - Nhẹ với Java Extension Pack

3. Tạo dự án đầu tiên của bạn

Trong IntelliJ IDEA:

  1. File → New → Project
  2. Chọn "Java" (chưa phải Java Enterprise hoặc Maven/Gradle)
  3. Đặt phiên bản JDK thành 17 hoặc 21
  4. Tạo dự án

Hello World:

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, Java!");
    }
}

Chạy nó: Nhấp chuột phải → Run 'HelloWorld.main()'

Điều gì đang xảy ra:

  • public class HelloWorld - Mọi tệp Java phải có một lớp
  • public static void main(String[] args) - Điểm vào cho các ứng dụng Java
  • System.out.println() - In ra console (giống như print() của Python hoặc console.log() của JavaScript)

Hệ thống kiểu của Java

Java là kiểu tĩnh và kiểu mạnh. Mọi biến phải có kiểu được khai báo.

Các kiểu nguyên thủy

Java có 8 kiểu nguyên thủy:

// Số nguyên
byte age = 25;              // 8-bit: -128 đến 127
short population = 30000;   // 16-bit: -32,768 đến 32,767
int count = 1000000;        // 32-bit: kiểu số nguyên phổ biến nhất
long bigNumber = 10000000000L;  // 64-bit: chú ý hậu tố 'L'
 
// Dấu phẩy động
float price = 19.99f;       // 32-bit: chú ý hậu tố 'f'
double pi = 3.14159265359;  // 64-bit: kiểu số thập phân phổ biến nhất
 
// Ký tự và Boolean
char grade = 'A';           // Ký tự Unicode 16-bit
boolean isActive = true;    // true hoặc false

Sự khác biệt chính so với Python/JavaScript:

  • Kiểu được khai báo tường minh, không suy luận (trước Java 10)
  • Không tự động chuyển đổi kiểu giữa các kiểu không tương thích
  • Kiểu nguyên thủy KHÔNG phải đối tượng (chúng không có phương thức)

Suy luận kiểu với var (Java 10+)

Java hiện đại hỗ trợ suy luận kiểu cục bộ:

// Thay vì:
String message = "Hello";
ArrayList<String> names = new ArrayList<>();
 
// Bạn có thể viết:
var message = "Hello";         // Kiểu được suy luận là String
var names = new ArrayList<String>();  // Kiểu được suy luận là ArrayList<String>

Quy tắc cho var:

  • Chỉ dành cho biến cục bộ (không phải trường hoặc tham số phương thức)
  • Yêu cầu khởi tạo (trình biên dịch cần suy luận kiểu)
  • Kiểu được cố định tại thời điểm biên dịch

Khi nào nên dùng var:

// Tốt: Kiểu rõ ràng
var username = "john_doe";
var count = 42;
var list = new ArrayList<String>();
 
// Tránh: Kiểu không rõ ràng
var result = doSomething();  // Đây là kiểu gì?

Các lớp bao bọc

Mỗi kiểu nguyên thủy có một lớp bao bọc tương ứng:

Integer age = 25;        // Bao bọc cho int
Double price = 19.99;    // Bao bọc cho double
Boolean isActive = true; // Bao bọc cho boolean

Tại sao các lớp bao bọc tồn tại:

  • Bộ sưu tập yêu cầu đối tượng (không thể lưu trữ kiểu nguyên thủy trực tiếp)
  • Cung cấp các phương thức tiện ích (ví dụ: Integer.parseInt())
  • Hỗ trợ khả năng null (kiểu nguyên thủy không thể là null)

Autoboxing và Unboxing:

// Autoboxing: nguyên thủy → bao bọc
int primitive = 42;
Integer wrapper = primitive;  // Chuyển đổi tự động
 
// Unboxing: bao bọc → nguyên thủy
Integer wrapped = 100;
int value = wrapped;  // Chuyển đổi tự động

Biến và hằng số

Khai báo biến

// Khai báo và khởi tạo
int count = 0;
String name = "Alice";
 
// Khai báo không khởi tạo
int value;
// value = ...; // Phải khởi tạo trước khi sử dụng
 
// Nhiều biến
int x = 10, y = 20, z = 30;

Hằng số

Sử dụng final cho hằng số:

final int MAX_SIZE = 100;
final double PI = 3.14159;
 
// MAX_SIZE = 200;  // Lỗi trình biên dịch: không thể gán lại

Quy ước đặt tên:

  • Biến: camelCase (ví dụ: userName, totalCount)
  • Hằng số: UPPER_SNAKE_CASE (ví dụ: MAX_VALUE, DEFAULT_TIMEOUT)
  • Lớp: PascalCase (ví dụ: UserService, OrderProcessor)

Luồng điều khiển

Câu lệnh điều kiện

if-else:

int score = 85;
 
if (score >= 90) {
    System.out.println("Grade: A");
} else if (score >= 80) {
    System.out.println("Grade: B");
} else if (score >= 70) {
    System.out.println("Grade: C");
} else {
    System.out.println("Grade: F");
}

Toán tử ba ngôi:

String result = score >= 60 ? "Pass" : "Fail";

Câu lệnh switch (truyền thống):

int day = 3;
String dayName;
 
switch (day) {
    case 1:
        dayName = "Monday";
        break;
    case 2:
        dayName = "Tuesday";
        break;
    case 3:
        dayName = "Wednesday";
        break;
    default:
        dayName = "Invalid day";
}

Biểu thức switch (Java 14+):

String dayName = switch (day) {
    case 1 -> "Monday";
    case 2 -> "Tuesday";
    case 3 -> "Wednesday";
    default -> "Invalid day";
};

Vòng lặp

Vòng lặp for:

for (int i = 0; i < 5; i++) {
    System.out.println("Count: " + i);
}

Vòng lặp for nâng cao (for-each):

String[] fruits = {"Apple", "Banana", "Orange"};
 
for (String fruit : fruits) {
    System.out.println(fruit);
}

Vòng lặp while:

int count = 0;
while (count < 5) {
    System.out.println(count);
    count++;
}

Vòng lặp do-while:

int i = 0;
do {
    System.out.println(i);
    i++;
} while (i < 5);

Phương thức

Phương thức trong Java tương tự như hàm trong các ngôn ngữ khác, nhưng chúng luôn là một phần của lớp.

Cú pháp phương thức cơ bản

public class Calculator {
    
    // Phương thức có giá trị trả về
    public int add(int a, int b) {
        return a + b;
    }
    
    // Phương thức không có giá trị trả về
    public void printSum(int a, int b) {
        System.out.println("Sum: " + (a + b));
    }
    
    // Phương thức với nhiều tham số
    public double calculateAverage(int[] numbers) {
        int sum = 0;
        for (int num : numbers) {
            sum += num;
        }
        return (double) sum / numbers.length;
    }
}

Các bổ từ phương thức

public class Example {
    
    // Public: có thể truy cập từ mọi nơi
    public void publicMethod() { }
    
    // Private: chỉ có thể truy cập trong lớp này
    private void privateMethod() { }
    
    // Static: thuộc về lớp, không phải instance
    public static void staticMethod() { }
    
    // Final: không thể ghi đè
    public final void finalMethod() { }
}

Nạp chồng phương thức

Java hỗ trợ nạp chồng phương thức (cùng tên, khác tham số):

public class MathOperations {
    
    public int add(int a, int b) {
        return a + b;
    }
    
    public double add(double a, double b) {
        return a + b;
    }
    
    public int add(int a, int b, int c) {
        return a + b + c;
    }
}
 
// Sử dụng
MathOperations math = new MathOperations();
int sum1 = math.add(5, 10);          // Gọi phương thức đầu tiên
double sum2 = math.add(5.5, 10.5);   // Gọi phương thức thứ hai
int sum3 = math.add(5, 10, 15);      // Gọi phương thức thứ ba

Mảng

Mảng trong Java có kích thước cố định và cấu trúc dữ liệu đồng nhất.

Khai báo và khởi tạo mảng

// Khai báo và khởi tạo
int[] numbers = {1, 2, 3, 4, 5};
 
// Khai báo với kích thước, sau đó khởi tạo
int[] values = new int[5];
values[0] = 10;
values[1] = 20;
// ...
 
// Độ dài mảng
System.out.println("Length: " + numbers.length);  // 5

Mảng đa chiều

// Mảng 2D
int[][] matrix = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};
 
// Truy cập phần tử
int value = matrix[1][2];  // 6
 
// Duyệt mảng 2D
for (int i = 0; i < matrix.length; i++) {
    for (int j = 0; j < matrix[i].length; j++) {
        System.out.print(matrix[i][j] + " ");
    }
    System.out.println();
}

Các thao tác mảng phổ biến

import java.util.Arrays;
 
int[] numbers = {5, 2, 8, 1, 9};
 
// Sắp xếp
Arrays.sort(numbers);  // {1, 2, 5, 8, 9}
 
// Tìm kiếm (yêu cầu mảng đã sắp xếp)
int index = Arrays.binarySearch(numbers, 5);  // 2
 
// Sao chép
int[] copy = Arrays.copyOf(numbers, numbers.length);
 
// Điền
int[] filled = new int[5];
Arrays.fill(filled, 10);  // {10, 10, 10, 10, 10}
 
// So sánh
boolean equal = Arrays.equals(numbers, copy);
 
// Chuyển đổi thành chuỗi
String arrayString = Arrays.toString(numbers);  // "[1, 2, 5, 8, 9]"

Chuỗi

Chuỗi trong Java là đối tượng, không phải kiểu nguyên thủy.

Cơ bản về chuỗi

// Chuỗi ký tự
String greeting = "Hello, World!";
 
// Nối chuỗi
String firstName = "John";
String lastName = "Doe";
String fullName = firstName + " " + lastName;
 
// Độ dài chuỗi
int length = greeting.length();  // 13
 
// Truy cập ký tự
char firstChar = greeting.charAt(0);  // 'H'

Các phương thức chuỗi phổ biến

String text = "  Hello, Java!  ";
 
// Chuyển đổi chữ hoa/thường
text.toUpperCase();        // "  HELLO, JAVA!  "
text.toLowerCase();        // "  hello, java!  "
 
// Loại bỏ khoảng trắng
text.trim();               // "Hello, Java!"
 
// Chuỗi con
text.substring(2, 7);      // "Hello"
 
// Thay thế
text.replace("Java", "World");  // "  Hello, World!  "
 
// Tách
String[] words = "apple,banana,orange".split(",");  // ["apple", "banana", "orange"]
 
// Kiểm tra nội dung
text.contains("Java");     // true
text.startsWith("  Hel");  // true
text.endsWith("va!  ");    // true
 
// So sánh
text.equals("Hello");      // false (nội dung khác)
text.equalsIgnoreCase("HELLO");  // false

Tính bất biến của chuỗi

Quan trọng: Chuỗi là bất biến trong Java!

String original = "Hello";
String modified = original.concat(" World");
 
System.out.println(original);  // "Hello" (không thay đổi)
System.out.println(modified);  // "Hello World" (chuỗi mới)

StringBuilder cho hiệu quả

Khi xây dựng chuỗi trong vòng lặp, sử dụng StringBuilder:

// Không hiệu quả (tạo nhiều đối tượng chuỗi)
String result = "";
for (int i = 0; i < 1000; i++) {
    result += i + ",";
}
 
// Hiệu quả (string builder có thể thay đổi)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append(i).append(",");
}
String result = sb.toString();

Text Blocks (Java 15+)

Cho chuỗi nhiều dòng:

String json = """
    {
        "name": "John Doe",
        "age": 30,
        "email": "[email protected]"
    }
    """;

Lớp và đối tượng cơ bản

Tạo một lớp đơn giản

public class Person {
    // Trường (biến instance)
    String name;
    int age;
    
    // Constructor
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    // Phương thức
    public void introduce() {
        System.out.println("Hi, I'm " + name + " and I'm " + age + " years old.");
    }
}
 
// Sử dụng
Person person = new Person("Alice", 25);
person.introduce();  // "Hi, I'm Alice and I'm 25 years old."

Getter và Setter

public class Account {
    private double balance;  // Trường private
    
    // Getter
    public double getBalance() {
        return balance;
    }
    
    // Setter
    public void setBalance(double balance) {
        if (balance >= 0) {
            this.balance = balance;
        }
    }
}

Chúng ta sẽ khám phá lớp và đối tượng chi tiết hơn trong Giai đoạn 2: Lập trình hướng đối tượng.

Mô hình biên dịch và thực thi

Java hoạt động như thế nào

  1. Viết mã nguồn Java (tệp .java)
  2. Biên dịch thành bytecode (tệp .class) sử dụng javac
  3. Thực thi bytecode trên JVM sử dụng java
# Biên dịch
javac HelloWorld.java
 
# Chạy
java HelloWorld

Java Virtual Machine (JVM)

Khái niệm chính: Java là "viết một lần, chạy mọi nơi"

  • Mã Java biên dịch thành bytecode (độc lập nền tảng)
  • JVM diễn giải bytecode cho HĐH cụ thể của bạn
  • Không cần biên dịch lại cho các nền tảng khác nhau

Điều này có nghĩa là:

  • Cùng một chương trình Java chạy trên Windows, macOS, Linux
  • Không cần build theo nền tảng cụ thể
  • JVM xử lý quản lý bộ nhớ (thu gom rác)

Thực hành tốt cho Giai đoạn 1

1. Tuân theo quy ước đặt tên

// Tốt
public class UserService { }
private String userName;
public static final int MAX_RETRY = 3;
 
// Xấu
public class userservice { }
private String UserName;
public static final int maxRetry = 3;

2. Sử dụng tên có ý nghĩa

// Tốt
int studentCount = 50;
String customerEmail = "[email protected]";
 
// Xấu
int n = 50;
String str = "[email protected]";

3. Giữ phương thức nhỏ gọn

// Tốt: Trách nhiệm đơn nhất
public boolean isValidEmail(String email) {
    return email != null && email.contains("@");
}
 
// Xấu: Quá nhiều trách nhiệm
public void processUser(String name, String email, int age) {
    // Xác thực tên
    // Xác thực email
    // Xác thực tuổi
    // Tạo user
    // Lưu vào cơ sở dữ liệu
    // Gửi email chào mừng
}

4. Sử dụng var khi kiểu rõ ràng

// Tốt
var username = "john_doe";
var count = users.size();
 
// Tránh
var data = process();  // Đây là kiểu gì?

Những cạm bẫy phổ biến

❌ Sử dụng == để so sánh chuỗi

String s1 = "hello";
String s2 = "hello";
String s3 = new String("hello");
 
s1 == s2;  // true (string pool)
s1 == s3;  // false (các đối tượng khác nhau)
 
// ✅ Luôn sử dụng .equals()
s1.equals(s3);  // true

❌ Chỉ số mảng vượt quá giới hạn

int[] numbers = {1, 2, 3};
int last = numbers[3];  // ArrayIndexOutOfBoundsException
 
// ✅ Sử dụng length - 1
int last = numbers[numbers.length - 1];

❌ Quên khởi tạo biến

int count;
System.out.println(count);  // Lỗi trình biên dịch
 
// ✅ Luôn khởi tạo
int count = 0;

❌ Sửa đổi mảng trong vòng lặp for nâng cao

int[] numbers = {1, 2, 3};
for (int num : numbers) {
    num = num * 2;  // Không sửa đổi mảng!
}
 
// ✅ Sử dụng vòng lặp for truyền thống
for (int i = 0; i < numbers.length; i++) {
    numbers[i] = numbers[i] * 2;
}

Bài tập thực hành

Củng cố kiến thức của bạn với các bài tập sau:

  1. Chuyển đổi nhiệt độ: Viết chương trình chuyển đổi Celsius sang Fahrenheit và ngược lại
  2. Thống kê mảng: Tính min, max, trung bình và tổng của một mảng số nguyên
  3. Đảo ngược chuỗi: Đảo ngược một chuỗi mà không sử dụng phương thức có sẵn
  4. Kiểm tra số nguyên tố: Xác định xem một số có phải là số nguyên tố không
  5. FizzBuzz: In các số từ 1-100, nhưng "Fizz" cho bội số của 3, "Buzz" cho 5, "FizzBuzz" cho cả hai

Tóm tắt

Bạn đã học được các nền tảng thiết yếu của Java:

✅ Thiết lập môi trường phát triển Java
✅ Hiểu hệ thống kiểu của Java (kiểu nguyên thủy, bao bọc, var)
✅ Sử dụng các cấu trúc điều khiển luồng (if, switch, vòng lặp)
✅ Viết phương thức với chữ ký phù hợp
✅ Làm việc với mảng và chuỗi
✅ Tạo các lớp và đối tượng cơ bản
✅ Hiểu mô hình biên dịch và thực thi

Bước tiếp theo

Bạn đã sẵn sàng chuyển sang Giai đoạn 2: Lập trình hướng đối tượng, nơi bạn sẽ học:

  • Lớp và đối tượng chi tiết
  • Kế thừa và đa hình
  • Interface và lớp trừu tượng
  • Đóng gói và bổ từ truy cập
  • Nguyên tắc và mẫu thiết kế

🚀 Tiếp tục đến Giai đoạn 2: Lập trình hướng đối tượng →


Trước đó: Lộ trình học Java ←
Tiếp theo: Giai đoạn 2: Lập trình hướng đối tượng →

Chúc bạn code vui vẻ! ☕

📬 Đăng ký nhận bản tin

Nhận những bài viết mới nhất qua email mỗi tuần. Không spam, hủy đăng ký bất cứ lúc nào.

Chúng tôi tôn trọng quyền riêng tư của bạn. Hủy đăng ký bất cứ lúc nào.

💬 Comments

Đăng nhập để bình luận

Chúng tôi sẽ không đăng bất cứ điều gì mà không có sự cho phép của bạn.