Bộ câu hỏi phỏng vấn Java phần 6

Annotations được sử dụng như thế nào và ở đâu trong Java?


Annotation được hiểu là một dạng chú thích hoặc một dạng siêu dữ liệu (metadata) được dùng để mô tả các meta-objects khác. Meta-objects là các classes, fields và methods. Các annotation không có ảnh hưởng trực tiếp đến hoạt động của mã mà chúng chú thích. Các annotation được sử dụng trong mã nguồn sẽ được biên dịch thành bytecode và sử dụng kỹ thuật phản chiếu (Reflection) để truy vấn thông tin siêu dữ liệu và đưa ra hành động thích hợp. Tiến trình annotation là một cơ chế rất mạnh mẽ và có thể được sử dụng theo nhiều cách khác nhau:

  • Để mô tả các ràng buộc hoặc cách sử dụng một phần tử: ví dụ: @Deprecated, @Override hoặc @NotNull
  • Để mô tả "bản chất" của một phần tử, ví dụ: @Entity, @TestCase, @WebService
  • Để mô tả hành vi của một phần tử: @Statefull, @Transaction
  • Để mô tả cách xử lý phần tử: @Column, @XmlElement

Ưu và nhược điểm của việc sử dụng một mảng không có thứ tự so với một mảng có thứ tự là gì?


Ưu điểm chính của mảng có thứ tự là thời gian tìm kiếm có độ phức tạp theo thời gian là O(log n), so với của mảng không có thứ tự, là O(n). Nhược điểm của mảng có thứ tự là thao tác chèn có độ phức tạp về thời gian là O(n), vì các phần tử có giá trị cao hơn phải được di chuyển để nhường chỗ cho phần tử mới. Thay vào đó, hoạt động chèn cho một mảng không có thứ tự cần thời gian không đổi là O(1).

Liệt kê các bước để một chương trình RMI hoạt động?


Các bước sau phải được thực hiện để chương trình RMI hoạt động bình thường:

  • Biên dịch tất cả các tệp nguồn.
  • Tạo ra các stubs bằng cách sử dụng rmic.
  • Khởi động rmiregistry.
  • Khởi động RMIServer.
  • Chạy chương trình client.

Sự khác biệt giữa Array và ArrayList là gì? Khi nào bạn sẽ sử dụng Array thay vì ArrayList?


Các lớp ArrayArrayList khác nhau về các tính năng sau:

  • Array có thể chứa các kiểu primitive hoặc các đối tượng, trong khi ArrayList chỉ có thể chứa các đối tượng.
  • Array có kích thước cố định, trong khi ArrayList là động (dynamic).
  • ArrayList cung cấp nhiều phương thức và tính năng hơn, chẳng hạn như addAll(), removeAll(), iterator, v.v.
  • Đối với danh sách các kiểu dữ liệu primitive, collection sử dụng autoboxing để giảm nỗ lực mã hóa. Tuy nhiên, cách tiếp cận này khiến chúng chậm hơn khi làm việc trên các kiểu dữ liệu primitive có kích thước cố định.

Deadlock là gì?


Khi hai process đang đợi lẫn nhau hoàn thành trước khi tiếp tục. Kết quả là cả hai process chờ đợi không ngừng. Trường hợp trên gọi là deadlock.

Sự khác biệt giữa ClassNotFoundException và NoClassDefFoundError là gì?


  • ClassNotFoundException có nghĩa là class file (tệp lớp) cho một class được yêu cầu không nằm trên classpath của ứng dụng.
  • NoClassDefFoundError cho biết rằng class file tồn tại trong runtime, nhưng vì lý do nào đó mà class không thể được chuyển thành một Class definition. Nguyên nhân phổ biến là một exception được thảy ra trong các khối khởi tạo tĩnh.

Nếu một đối tượng được gán thành null, Garbage Collector có giải phóng ngay bộ nhớ được giữ bởi đối tượng đó không?


Không, đối tượng sẽ được thu gom rác trong chu kỳ tiếp theo của Garbage Collector.

Constructor, Constructor Overloading trong Java và Copy-Constructor là gì?


  • Một constructor được gọi khi một đối tượng mới được tạo. Mỗi class đều có một phương thức constructor. Trong trường hợp người lập trình không cung cấp constructor cho một class, trình biên dịch Java (Javac) sẽ tạo một hàm constructor mặc định cho class đó.
  • Constructor overloading tương tự như method overloading trong Java. Một class có thể có nhiều hàm constructor khác nhau. Mỗi hàm constructor phải có danh sách tham số duy nhất của riêng nó.
  • Cuối cùng, Java có hỗ trợ các hàm copy-constructor (hàm tạo sao chép) như C ++, nhưng sự khác biệt nằm ở thực tế là Java không tự tạo một hàm copy-constructor mặc định nếu bạn không viết riêng.

Sự khác biệt giữa throw và throws là gì?


Từ khóa throw được sử dụng để nêu rõ một exception trong chương trình. Ngược lại, mệnh đề throws được sử dụng để chỉ ra những exceptions không được xử lý bởi một phương thức. Mỗi phương thức phải chỉ định rõ ràng những exceptions nào không xử lý, vì vậy những người gọi phương thức đó có thể đề phòng các exceptions có thể xảy ra. Cuối cùng, các exceptions được phân tách bằng dấu phẩy.

Java Priority Queue là gì?


  • PriorityQueue là một hàng đợi (queue) không bị ràng buộc, dựa trên một heap ưu tiên và các phần tử của nó được sắp xếp theo thứ tự tự nhiên của chúng.
  • Tại thời điểm tạo, chúng ta có thể cung cấp một Comparator chịu trách nhiệm sắp xếp thứ tự các phần tử của PriorityQueue.
  • PriorityQueue không cho phép các giá trị null, những đối tượng không cung cấp thứ tự tự nhiên hoặc những đối tượng không có bất kỳ comparator nào được liên kết với chúng.
  • Cuối cùng, Java PriorityQueue không phải là thread-safe và nó yêu cầu thời gian O(log (n)) cho các hoạt động sắp xếp và xếp hàng của nó.

Vai trò của stub trong RMI (Remote Method Invocation) là gì?


Một stub cho một remote object hoạt động như một đại diện cục bộ của client hoặc proxy cho remote object. Người gọi gọi một phương thức trên stub cục bộ, phương thức này chịu trách nhiệm thực thi phương thức trên remote object. Khi phương thức của một stub được gọi, nó sẽ trải qua các bước sau:

  • Khởi tạo kết nối tới remote-JVM có chứa remote object.
  • Sắp xếp các tham số cho remote-JVM.
  • Đợi kết quả của việc gọi và thực thi phương thức.
  • Giải nén giá trị trả về hoặc một exception nếu phương thức không được thực thi thành công.
  • Trả về giá trị cho người gọi.

Điều gì xảy ra khi một applet được tải?


Trước hết, một instance của lớp điều khiển của applet được tạo. Sau đó, applet tự khởi tạo và cuối cùng, nó bắt đầu chạy.

Sự khác biệt giữa Applet và Servlet là gì?


  • Applet là một chương trình java chạy trong trình duyệt Web phía client. Mặt khác, một Servlet là một thành phần phía server chạy trên máy chủ web.
  • Một applet có thể sử dụng các lớp UI, trong khi một servlet không có UI. Thay vào đó, một servlet chờ các HTTP request của client và tạo response trong mọi request.

Trình bày vòng đời (life cycle) của Servlet?


  • Theo request của các client, Servlet Engine tải các servlet và gọi các phương thức init của nó, để khởi tạo servlet.
  • Sau đó, đối tượng Servlet xử lý tất cả các request tiếp theo đến từ client đó, bằng cách gọi phương thức service cho từng request.
  • Cuối cùng, servlet bị xóa bằng cách gọi phương thức destroy của server.

Có thể sử dụng == trên enum không?


Có, enums có các điều khiển instance chặt chẽ cho phép bạn sử dụng == để so sánh các instances. Đây là sự đảm bảo được cung cấp bởi đặc tả ngôn ngữ.

Làm sao để đồng bộ hóa hai Java processes?


Không thể làm điều gì đó như bạn muốn trong Java. Các ứng dụng Java khác nhau sẽ sử dụng các JVM khác nhau tự phân tách hoàn toàn thành các 'hộp đen' khác nhau. Tuy nhiên, bạn có 2 lựa chọn:

  • Sử dụng sockets (hoặc channels). Về cơ bản, một ứng dụng sẽ mở listening socket và bắt đầu đợi cho đến khi nó nhận được tín hiệu nào đó. Ứng dụng khác sẽ kết nối ở đó và gửi tín hiệu khi nó đã hoàn thành một việc gì. Tôi muốn nói rằng đây là cách ưa thích được sử dụng trong 99,9% ứng dụng.
  • Bạn có thể gọi winapi từ Java (trên windows).

Làm cách nào để thoát khỏi các vòng lặp lồng nhau trong Java?


Làm thế nào tôi có thể thoát ra khỏi cả hai vòng lặp?

for (Type type : types) {
   for (Type t : types2) {
      if (some condition) {
         // Do something and break...
         break; // Breaks out of the inner loop
      }
   }
}

Giải pháp: Bạn có thể sử dụng "break" với một label cho vòng lặp ngoài.

Ví dụ:

public class Test {
   public static void main(String[] args) {
      outerloop:
      for (int i=0; i < 5; i++) {
         for (int j=0; j < 5; j++) {
            if (i * j > 6) {
               System.out.println("Breaking");
               break outerloop;
            }
            System.out.println(i + " " + j);
         }
      }
      System.out.println("Done");
   }
}
Avatar Techmely Team
VIẾT BỞI

Techmely Team