JAVA CORE
JAVA CORE
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

Câu hỏi phỏng vấn JavaCore phần 2

Để giúp bạn có thể chuẩn bị tốt nhất, hôm nay freetuts sẽ tiếp tục series các câu hỏi phỏng vấn JavaCore. Dưới đây là những câu hỏi thường gặp khi bạn đi phỏng vấn JavaCore.

test php

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

Câu 1: Hãy trình bày hiểu biết của bạn về JVM, JRE, JDK?

  • JVM, JRE và JDK là các khái niệm liên quan đến Java và môi trường thực thi Java.

  • JVM (Java Virtual Machine):

JVM là một máy ảo Java, là thành phần chính của Java Runtime Environment (JRE). JVM được sử dụng để thực thi mã Java, nó chuyển đổi mã Java được viết bằng ngôn ngữ Java thành mã máy được hiểu bởi hệ điều hành. JVM có thể chạy trên nhiều nền tảng khác nhau như Windows, Linux, Mac, v.v.

  • JRE (Java Runtime Environment):

JRE bao gồm JVM và các thư viện Java cần thiết để thực thi các ứng dụng Java. JRE được sử dụng để chạy các ứng dụng Java trên máy tính. Nó cung cấp môi trường thực thi cho các ứng dụng Java.

  • JDK (Java Development Kit):

JDK là bộ công cụ phát triển Java, bao gồm JRE và các công cụ cần thiết để phát triển ứng dụng Java, bao gồm trình biên dịch Java (javac), trình tạo JAR (jar), trình quản lý gói (pkgmgr), v.v. JDK cung cấp môi trường phát triển hoàn chỉnh để phát triển các ứng dụng Java.

Bài viết này được đăng tại [free tuts .net]

Câu 2: Tại sao Java được gọi là “Write once, run anywhere” ?

  • Java được gọi là "write once, run anywhere" bởi vì ngôn ngữ lập trình Java cho phép người lập trình viết mã chỉ một lần và chạy trên nhiều nền tảng khác nhau mà không cần thay đổi mã nguồn.

Giải thích:

  • JVM cung cấp một môi trường thực thi độc lập với hệ điều hành và phần cứng.

  • Khi bạn viết mã Java, mã đó được biên dịch thành bytecode, một ngôn ngữ trung gian được hiểu bởi JVM. Khi chạy chương trình, JVM sẽ biên dịch bytecode thành mã máy thích hợp cho nền tảng đang chạy. Do đó, chương trình Java có thể chạy trên bất kỳ hệ điều hành nào có JVM tương ứng.sdY 8tHhhVigGc8fhAcAWQLF A17rQNk5plkYr GCHkdbR N wihwbdK1JgN8MhtlgBe56T iRIdb 1eov3mySf1OMhnvtg iaX PjKlcWyVczPJABBhnyI UZfS0r8qWwJ0BJiya K6Enk9DIZjlwE

  • Điều này giúp tiết kiệm thời gian và công sức cho các lập trình viên, vì họ không cần phải viết mã khác nhau cho từng nền tảng. Nó cũng giúp đơn giản hóa việc phát triển và bảo trì ứng dụng, vì chỉ cần phát triển và kiểm thử trên một nền tảng và sau đó chạy trên nhiều nền tảng khác nhau mà không cần chỉnh sửa lại mã nguồn.

Câu 3: So sánh sự khác nhau giữa int và Integer trong Java?

Để dễ hình dung thì chúng ta có bảng sau:

int

Integer

Là kiểu dữ liệu nguyên thủy

Là một lớp trong Java

Không thể được gán giá trị null

Có thể null

Sử dụng để lưu trữ giá trị số nguyên

Sử dụng để lưu trữ giá trị số nguyên

Có giá trị mặc định là 0

Có giá trị mặc định là null

Thực hiện các phép toán số học trực tiếp

Để thực hiện các phép toán số học cần phải sử dụng phương thức của lớp Integer

Có thể sử dụng trong các cấu trúc điều khiển, ví dụ như switch case

Cần phải sử dụng phương thức intValue() để chuyển đổi thành kiểu dữ liệu nguyên thủy để sử dụng trong các cấu trúc điều khiển

Sử dụng ít bộ nhớ

Sử dụng nhiều bộ nhớ hơn so với int do nó là một lớp và bao gồm các phương thức và thông tin phụ

Không thể sử dụng các cấu trúc dữ liệu yêu cầu đối tượng như ArrayList

Có thể sử dụng được các cấu trúc dữ liệu yêu cầu đối tượng.

Câu 4: So sánh bộ nhớ Stack và Heap?

  • Bộ nhớ Stack (hay còn gọi là ngăn xếp) là một vùng nhớ trong máy tính được sử dụng để lưu trữ các biến cục bộ và tham số của hàm trong quá trình thực thi của một chương trình. Khi một hàm được gọi, các tham số và biến cục bộ của hàm đó được lưu trữ trên bộ nhớ Stack và khi hàm đó hoàn thành thì các giá trị này sẽ bị xóa khỏi bộ nhớ Stack.

  • Bộ nhớ Heap là một vùng nhớ trong máy tính được sử dụng để lưu trữ các đối tượng và mảng trong quá trình thực thi của một chương trình. Khi một đối tượng được tạo ra, nó được lưu trữ trên bộ nhớ Heap và khi không còn được sử dụng thì được giải phóng để tránh lãng phí tài nguyên bộ nhớ.

Dưới đây là bảng so sánh sự khác nhau giữa 2 bộ nhớ trên.

Bộ nhớ Stack

Bộ nhớ Heap

Mục đích

Lưu trữ các biến cục bộ và tham số của các hàm trong quá trình thực thi

Lưu trữ các đối tượng và mảng trong quá trình thực thi

Quản lý

Được quản lí bởi Hệ điều hành

Được quản lý bởi trình quản lý bộ nhớ JVM

Tổ chức

Tổ chức theo cơ chế ngăn xếp(LIFO)

Tổ chức theo cơ chế bảng điểm(hash table)

Số lượng

nhỏ hơn

lớn hơn

Thời gian sống

Thời gian sống của các biến cục bộ và tham số của hàm ngắn hơn thời gian sống của các đối tượng trên Heap

Thời gian sống của các đối tượng Heap dài hơn thời gian sống của các biến cục bộ

Cơ chế giải phóng

Tự động giải phóng khi hàm thực thi hoàn tất

Được giải phóng bởi trình quản lý bộ nhớ khi không còn được tham chiếu

(Việc hiểu rõ sự khác nhau giữa hai loại bộ nhớ này rất quan trọng đối với các lập trình viên Java để tối ưu hóa sử dụng tài nguyên bộ nhớ của chương trình.)

Câu 5: Hãy trình bày hiểu biết về tính đa hình trong lập trình hướng đối tượng.

  • Khái niệm: Tính đa hình (Polymorphism) là một khái niệm trong lập trình hướng đối tượng mô tả khả năng của đối tượng để có thể hiểu và đáp ứng các yêu cầu khác nhau của chương trình một cách linh hoạt.

  • Vai trò của tính đa hình:

  • Cho phép các đối tượng của các lớp khác nhau sử dụng một phương thức hoặc gọi một phương thức cùng tên nhưng có tham số và giá trị trả về khác nhau để thực hiện một hành động tương tự.

/**
 * học lập trình cùng Freetuts
 * Freetuts.net
 */
class Animal{
    public void makeSound(){
        System.out.println("The animal makes a sound");
    }
}

class Cat extends Animal{
    public void makeSound(){
        System.out.println("Meow");
    }
}

class Dog extends Animal{
    public void makeSound(){
        System.out.println("Woof");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal myPet = new Cat();
        myPet.makeSound();// prints Meow
        myPet = new Dog();
        myPet.makeSound(); // prints Woof  
    }
}
  • Tính đa hình giúp cho việc lập trình trở nên dễ dàng hơn và linh hoạt hơn. Nó cho phép lập trình viên tái sử dụng lại mã nguồn, giảm thiểu lượng mã phức tạp và dễ dàng bảo trì các chương trình.

  • Tính đa hình cho phép các đối tượng có thể được truy cập thông qua các giao diện chung, giúp cho việc phát triển và sử dụng các thư viện và khung làm việc trở nên dễ dàng hơn.

  • Nhược điểm của tính đa hình:

  • Khó triển khai : Khi sử dụng tính đa hình, người đọc và người sử dụng mã có thể gặp khó khăn trong việc hiểu hoạt động của chương trình, vì các phương thức có thể có các hành vi khác nhau với cùng một tên.

  • Không đảm bảo kiểm tra lỗi tại thời điểm biên dịch: Vì các phương thức được gọi động tại thời điểm chạy, nên các lỗi được phát hiện tại thời điểm chạy chương trình, chứ không phải tại thời điểm biên dịch.

  • Không phù hợp với các hệ thống lớn và phức tạp: Khi sử dụng tính đa hình trong các hệ thống lớn và phức tạp, có thể dẫn đến việc các phương thức bị lỗi hoặc xung đột, do đó cần có sự kiểm soát cẩn thận khi thiết kế và triển khai hệ thống.

  • Yêu cầu cấu trúc phức tạp: Tính đa hình có thể yêu cầu cấu trúc phức tạp để thực hiện, ví dụ như phải sử dụng các giao diện và lớp trừu tượng, đòi hỏi sự hiểu biết chuyên sâu về lập trình hướng đối tượng.

  • Phân loại: Đa hình được chia thành 2 loại là Overloading và Overriding

Freetuts đã viết một bài phân tích về 2 loại đa hình trên ở link này:

Overriding và Overloading trong Java.

Câu 6: Phân biệt ArrayList và LinkedList

  • Khái niệm:

  • ArrayList là một danh sách động (dynamic list), được triển khai dựa trên mảng (array) có kích thước thay đổi được.Các phần tử trong ArrayList được lưu trữ dưới dạng một mảng đối tượng, và khi số lượng phần tử trong danh sách thay đổi, kích thước của mảng cũng sẽ được điều chỉnh tương ứng.

  • LinkedList là một danh sách liên kết (linked list), được triển khai dựa trên cấu trúc các node liên kết với nhau. Mỗi node sẽ lưu trữ giá trị và một tham chiếu đến node kế tiếp trong danh sách.

Dưới đây là bảng so sánh giữa ArrayList và LinkedList:

Tính năng

ArrayList

LinkedList

Cấu trúc dữ liệu

Mảng

Danh sách liên kết

Thao tác truy cập

O(1)

O(n)

Thao tác chèn, xóa

O(n)

O(1)

Sử dụng bộ nhớ

Tốn bộ nhớ cho mảng

Không tốn bộ nhớ cho mảng

Sử dụng tài nguyên

Cần tài nguyên hơn nếu kích thước danh sách lớn

Cần ít tài nguyên hơn nếu kích thước danh sách lớn

Sử dụng trong trường hợp nào?

Nên sử dụng khi cần thao tác truy cập nhiều hơn là chèn, xóa

Nên sử dụng khi cần thao tác chèn, xóa phần tử nhiều hơn là truy cập

Câu 7: Trình bày các đặc điểm của HashSet

  • Khái niệm: HashSet là một cấu trúc dữ liệu trong Java, được sử dụng để lưu trữ tập hợp các phần tử duy nhất (distinct elements).

  • Các đặc điểm chính của HashSet bao gồm:

  • Không cho phép phần tử trùng lặp: HashSet sử dụng thuật toán băm (hashing) để lưu trữ các phần tử. Mỗi phần tử sẽ được gán một giá trị băm (hash code) và được lưu trữ trong một vị trí tương ứng trong bảng băm (hash table). Với cùng một giá trị băm, các phần tử được so sánh với nhau bằng phương thức equals() để đảm bảo tính duy nhất của tập hợp.

  • Tốc độ truy cập nhanh: HashSet sử dụng cấu trúc bảng băm (hash table) để lưu trữ các phần tử. Vì vậy, việc truy cập các phần tử bất kỳ trong tập hợp có độ phức tạp gần như là O(1).

  • Không lưu trữ thứ tự các phần tử: Các phần tử trong HashSet không được lưu trữ theo thứ tự cụ thể. Khi duyệt các phần tử trong HashSet, thứ tự xuất hiện của chúng có thể khác nhau so với thứ tự được thêm vào ban đầu.

  • Cho phép null: HashSet cho phép lưu trữ phần tử null.

  • Có thể được sử dụng trong các thuật toán băm (hashing): HashSet cung cấp một cấu trúc dữ liệu tương đối đơn giản và linh hoạt, có thể được sử dụng trong các thuật toán băm để giải quyết các bài toán liên quan đến lưu trữ tập hợp phần tử duy nhất.

Dưới đây là một ví dụ cụ thể về đặc điểm của HashSet:

import java.util.HashSet;
//Học lập trình cùng Freetuts
public class HashSetExample {
   public static void main(String[] args) {
       //Khởi tạo một HashSet
       HashSet<String> set = new HashSet<>();

       //Thêm các phần tử vào tập hợp
       set.add("apple");
       set.add("banana");
       set.add("orange");
       set.add("kiwi");
       set.add("pineapple");

       //Đặt vào một phần tử trùng lặp
       set.add("banana");

       //In ra tập hợp
       System.out.println("Tập hợp sau khi thêm các phần tử: " + set);

       //Truy cập một phần tử trong tập hợp
       String element = "kiwi";
       if (set.contains(element)){
           System.out.println(element + "có trong tập hợp");
       } else {
           System.out.println(element + "không có trong tập hợp");
       }

       //Xóa một phần tử trong tập hợp
       String toRemove = "orange";
       set.remove(toRemove);
       System.out.println("Tập hợp sau khi xóa " + toRemove + ": " + set);
    
       //Lấy số phần tử trong tập hợp
       System.out.println("Số phần tử trong tập hợp: " + set.size());
    
       //Kiểm tra tập hợp có trống hay không ?
       System.out.println("Tập hợp có trống hay không? " + set.isEmpty());  

       //Duyệt tất cả các phần tử trong tập hợp
       System.out.println("Duyệt tất cả các phần tử trong tập hợp: ");
       for (String s: set){
           System.out.println(s);
       }
   }
}

Kết quả của chương trình như sau:

Tập hợp sau khi thêm các phần tử: [banana, orange, apple, kiwi, pineapple]
kiwi có trong tập hợp
Tập hợp sau khi xóa orange: [banana, apple, kiwi, pineapple]
Số phần tử trong tập hợp: 4
Tập hợp có trống hay không? false
Duyệt tất cả các phần tử trong tập hợp: 
banana
apple
kiwi
pineapple

Như vậy, ta có thể thấy rằng:

  • HashSet không cho phép lưu trữ các phần tử trùng lặp.

Trong ví dụ này, khi ta thêm phần tử "banana" vào HashSet lần thứ hai, phần tử này không được thêm vào tập hợp.

  • HashSet cho phép truy cập phần tử trong tập hợp với tốc độ O(1).

Khi ta kiểm tra xem phần tử "kiwi" có trong tập hợp hay không, chương trình có thể truy cập phần tử này trong thời gian rất ngắn.

  • HashSet không giữ thứ tự của các phần tử.

Trong ví dụ này, khi ta thêm các phần tử vào HashSet, thứ tự các phần tử được sắp xếp một cách ngẫu nhiên. Khi ta duyệt qua tất cả các phần tử trong HashSet, thứ tự của các phần tử được in ra theo thứ tự mà HashSet tự động xác định.

  • HashSet cho phép xóa phần tử trong tập hợp.

Khi ta xóa phần tử "orange" khỏi HashSet, phần tử này được loại bỏ khỏi tập hợp.

  • HashSet cho phép lấy số phần tử trong tập hợp với tốc độ O(1).

Trong ví dụ này, khi ta gọi phương thức size() để lấy số phần tử trong HashSet, phương thức này trả về kết quả ngay lập tức.

  • HashSet cung cấp phương thức isEmpty() để kiểm tra xem tập hợp có trống hay không. Khi tập hợp không chứa phần tử nào, phương thức này trả về giá trị true.

audio png

/**

* learning setup freetuts free

* Freetuts.net

*/

lớp Động vật{

public void makeSound(){

System.out.println("Con vật kêu");

}

}

lớp Mèo mở rộng Động vật{

public void makeSound(){

System.out.println("Meo meo");

}

}

lớp Chó mở rộng Động vật{

public void makeSound(){

System.out.println("Gâu");

}

}

lớp công khai Chính {

public static void main(String[] args) {

MyPet động vật = con mèo mới();

myPet.makeSound();// in Meow

myPet = Con chó mới();

myPet.makeSound(); // in Gâu

}

}

audio png

chèn file

audio png

bảng băm

Cùng chuyên mục:

Hướng dẫn Upload file với Spring Boot và jQuery Ajax trong Java

Hướng dẫn Upload file với Spring Boot và jQuery Ajax trong Java

Hướng dẫn download file với Spring Boot trong Java

Hướng dẫn download file với Spring Boot trong Java

Hướng dẫn Upload file với Spring Boot trong Java

Hướng dẫn Upload file với Spring Boot trong Java

Hướng dẫn CRUD với Spring Boot, REST và AngularJS trong Java

Hướng dẫn CRUD với Spring Boot, REST và AngularJS trong Java

Cách sử dụng Spring  Scheduled trong Spring Boot

Cách sử dụng Spring Scheduled trong Spring Boot

Cách dùng Groovy trong Spring Boot Java

Cách dùng Groovy trong Spring Boot Java

Cách dùng Spring Boot và Mustache trong Java

Cách dùng Spring Boot và Mustache trong Java

Cách dùng Spring Boot và MongoDB trong Java

Cách dùng Spring Boot và MongoDB trong Java

Cách tạo Restful Client bằng RestTemplate trong Spring Boot

Cách tạo Restful Client bằng RestTemplate trong Spring Boot

Hướng dẫn sử dụng Interceptor trong Spring Boot

Hướng dẫn sử dụng Interceptor trong Spring Boot

Sử dụng Twitter Bootstrap trong Spring Boot

Sử dụng Twitter Bootstrap trong Spring Boot

Tạo trang web đa ngôn ngữ với Spring Boot trong Java

Tạo trang web đa ngôn ngữ với Spring Boot trong Java

Tạo ứng dụng Chat với Spring Boot và Websocket

Tạo ứng dụng Chat với Spring Boot và Websocket

Sử dụng JUnit để tạo unit test trong Spring Boot

Sử dụng JUnit để tạo unit test trong Spring Boot

Cách triển khai Spring Boot trên Tomcat Server

Cách triển khai Spring Boot trên Tomcat Server

Cách test RESTful API trong Spring Boot

Cách test RESTful API trong Spring Boot

Cách dùng Spring Security trong Spring Boot để xác thực và phân quyền

Cách dùng Spring Security trong Spring Boot để xác thực và phân quyền

Duyệt cây nhị phân bằng phương pháp inOder trong Java

Duyệt cây nhị phân bằng phương pháp inOder trong Java

Xóa node của cây nhị phân tìm kiếm trong Java

Xóa node của cây nhị phân tìm kiếm trong Java

Bảo mật Spring Boot RESTful Service sử dụng Basic Authentication trong Java

Bảo mật Spring Boot RESTful Service sử dụng Basic Authentication trong Java

Top