71. Điều gì sẽ xảy ra nếu chúng ta không ghi đè phương thức toString() của Enum?
Giả sử chúng ta có enum sau :public enum Role {
STUDENT,
TEACHER,
DIRECTOR,
SECURITY_GUARD;
}
Hãy hiển thị học sinh trong bảng điều khiển bằng cách gọi toString() cho học sinh đó :
System.out.println(Role.STUDENT.toString());
Kết quả trong bảng điều khiển:
72. Có thể chỉ định một hàm tạo bên trong Enum không?
Vâng, chắc chắn rồi. Thông qua hàm tạo, các giá trị của các biến enum bên trong được thiết lập. Ví dụ: hãy thêm hai trường vào enum trước đó - ageFrom và ageTo - để biểu thị độ tuổi cho từng vai trò:public enum Role {
STUDENT(5,18),
TEACHER(20,60),
DIRECTOR(40,70),
SECURITY_GUARD(18,50);
int ageFrom;
int ageTo;
Role(int ageFrom, int ageTo) {
this.ageFrom = ageFrom;
this.ageTo = ageTo;
}
}
73. Sự khác biệt giữa == và bằng() là gì?
Đây là một trong những câu hỏi phỏng vấn lập trình viên Java phổ biến nhất. Hãy bắt đầu với thực tế là khi chúng ta so sánh các giá trị đơn giản ( int , char , double ...), chúng ta thực hiện bằng cách sử dụng == , vì các biến chứa các giá trị cụ thể và chúng ta có thể so sánh chúng. Và các biến nguyên thủy không phải là đối tượng chính thức - chúng không kế thừa từ Object và không có phương thức bằng() . Khi chúng ta nói về việc so sánh các biến tham chiếu đến các đối tượng, == sẽ chỉ so sánh giá trị của các tham chiếu - cho dù chúng có tham chiếu đến cùng một đối tượng hay không. Và ngay cả khi một đối tượng giống hệt một đối tượng khác, việc so sánh qua == sẽ cho kết quả âm tính ( false ), vì đây là một đối tượng khác. Như bạn đã hiểu, phương thức Equals() được sử dụng để so sánh các biến tham chiếu . Đây là một trong những phương thức tiêu chuẩn của lớp Object , cần thiết để so sánh đầy đủ các đối tượng. Nhưng cần phải làm rõ ngay: để phương thức này hoạt động chính xác, nó cần được xác định lại bằng cách viết chính xác cách so sánh các đối tượng của lớp này. Trừ khi bạn ghi đè phương thức, theo mặc định, nó sẽ so sánh các đối tượng bằng == . Trong IntelliJ IDEA , bạn có thể ghi đè tự động (sử dụng công cụ IDEA) -> alt + Insert , trong cửa sổ xuất hiện, chọn Equals() và hashCode() -> chọn trường lớp nào sẽ tham gia -> và voila, tự động triển khai các phương pháp đã hoàn tất. Dưới đây là một ví dụ về phương thức bằng được tạo tự động sẽ trông như thế nào đối với một lớp Cat đơn giản có hai trường - int age và String name :@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || this.getClass() != o.getClass()) return false;
final Cat cat = (Cat) o;
return this.age == cat.age &&
Objects.equals(this.name, cat.name);
}
Nếu chúng ta nói về sự khác biệt giữa == và bằng với enums thì không có gì nhiều. Xét cho cùng, enum lưu trữ các hằng số và ngay cả khi so sánh các giá trị tương tự bằng cách sử dụng == , chúng ta sẽ nhận được true , vì các tham chiếu sẽ luôn hướng đến cùng một đối tượng. Chà, khi sử dụng bằng, chúng ta cũng sẽ tìm ra chức năng một cách chính xác, đặc biệt nếu bạn đi sâu vào phần thân của phương thức bằng cho một enum , bạn sẽ thấy rằng trong lớp Enum cách triển khai phương thức như sau: Tức là, bên trong - sự so sánh cũ tốt bằng cách tham khảo! Tóm lại: đối với enum , so sánh cả thông qua == và bằng đều đúng.
74. Phương thức ordinal() trong Enum làm gì?
Khi gọi phương thức int ordinal() trên một phần tử enum , chúng ta sẽ nhận được số thứ tự từ 0 của giá trị này trong chuỗi liệt kê tổng quát. Hãy sử dụng phương pháp này trên một phần tử từ enum đã thảo luận trước đó - Vai trò :System.out.println(Role.DIRECTOR.ordinal());
Theo đó, giao diện điều khiển sẽ hiển thị:
75. Có thể sử dụng Enum với TreeSet hoặc TreeMap trong Java không?
Việc sử dụng các loại enum trong TreeSet và TreeMap là chấp nhận được. Và chúng ta có thể viết:TreeSet<Role> treeSet = new TreeSet<>();
treeSet.add(Role.SECURITY_GUARD);
treeSet.add(Role.DIRECTOR);
treeSet.add(Role.TEACHER);
treeSet.add(Role.STUDENT);
treeSet.forEach(System.out::println);
Và bảng điều khiển sẽ hiển thị:
76. Phương thức ordinal() và so sánhTo() có liên quan như thế nào trong Enum?
Như đã nêu trước đó, ordinal() trả về số thứ tự của một giá trị trong danh sách liệt kê chung. Ngoài ra, khi phân tích câu hỏi trước, bạn đã thấy rằng các phần tử của bảng liệt kê, chẳng hạn, một lần trong TreeSet (tập hợp được sắp xếp) sẽ có thứ tự được khai báo trong enum . Và như chúng ta đã biết, TreeSet và TreeMap sắp xếp các phần tử bằng cách gọi phương thức so sánhTo() của giao diện Comparable . Từ đó, chúng ta có thể giả định rằng lớp Enum triển khai giao diện Comparable , triển khai nó trong phương thức so sánhTo() , trong đó ordinal() được sử dụng để đặt thứ tự sắp xếp. Sau khi vào lớp Enum , chúng ta thấy xác nhận về điều này: Và phần thân của chính phương thức: Phương thức ordinal() không được gọi ở đây. Thay vào đó, biến thứ tự được sử dụng - số thứ tự của phần tử trong bảng liệt kê. Bản thân phương thức ordinal() không gì khác hơn là một getter cho biến thứ tự .77. Viết ví dụ EnumM
Trong các câu hỏi được thảo luận ở trên, tôi đã đưa ra các ví dụ về enum và tôi không thấy việc sao chép mã có ý nghĩa gì (ví dụ: câu hỏi số 72 về hàm tạo trong enum).78. Có thể sử dụng Enum trong trường hợp switch không?
Có thể và cần thiết! Nhìn lại quá trình thực hành của mình, tôi lưu ý rằng một trong những nơi phổ biến nhất để sử dụng enum là các cấu trúc logic như switch . Trong trường hợp này, bạn có thể cung cấp tất cả các biến thể có thể có của case và sau khi viết logic cho tất cả các giá trị enum - và việc sử dụng toán tử mặc định thậm chí có thể không cần thiết! Xét cho cùng, nếu bạn sử dụng một Chuỗi hoặc một giá trị số, chẳng hạn như loại int , thì bạn có thể nhận được một giá trị không mong muốn, do đó, bạn không thể sử dụng giá trị này bằng enum . Công tắc sẽ trông như thế nào trong ví dụ đã thảo luận trước đó:public void doSomething(Role role) {
switch (role) {
case STUDENT:
// некая логика для STUDENT
break;
case TEACHER:
// некая логика для TEACHER
break;
case DIRECTOR:
// некая логика для DIRECTOR
break;
case SECURITY_GUARD:
// некая логика для SECURITY_GUARD
break;
}
}
79. Làm cách nào để lấy tất cả các giá trị có sẵn trong một instance Enum?
Nếu bạn cần lấy tất cả các phiên bản của một bảng liệt kê, thì có một phương thức value() trả về một mảng gồm tất cả các giá trị có sẵn của một enum cụ thể theo thứ tự tự nhiên (theo thứ tự chúng được chỉ định trong enum ). Ví dụ:Role[] roles = Role.values();
for (Role role : roles) {
System.out.println(role);
}
Bảng điều khiển sẽ hiển thị đầu ra sau:
API luồng
80. Luồng trong Java là gì?
Luồng Java là một cách tương tác tương đối mới với luồng dữ liệu, do đó cho phép bạn xử lý dữ liệu lớn một cách thuận tiện và gọn gàng hơn, cũng như xử lý song song giữa một số luồng nhất định, có thể tăng hiệu suất trong quá trình sử dụng. chức năng. Chủ đề này không thể thảo luận sâu hơn một cách ngắn gọn, vì vậy tôi sẽ để lại ở đây một liên kết đến một bài viết có thể giúp bạn đi sâu vào chủ đề này.81. Đặc điểm chính của giao dịch là gì?
Chủ đề có tên là Stream API, nhưng câu hỏi là về giao dịch. Hmm... Đầu tiên, hãy tìm hiểu giao dịch là gì. Giao dịch là một nhóm các thao tác cơ sở dữ liệu tuần tự đại diện cho một đơn vị logic làm việc với dữ liệu. Một giao dịch có thể được hoàn thành toàn bộ và thành công, duy trì tính toàn vẹn dữ liệu và độc lập với các giao dịch khác chạy song song hoặc không thể hoàn thành được, trong trường hợp đó, giao dịch đó không có hiệu lực. Vì vậy, các giao dịch có bốn thuộc tính chính, được gọi tắt là ACID . Chúng ta hãy xem mỗi chữ cái trong chữ viết tắt này là viết tắt của: A - Tính nguyên tử - tính nguyên tử - thuộc tính này đảm bảo rằng sẽ không có giao dịch nào được ghi lại một phần trong hệ thống. Tất cả các hoạt động phụ của nó sẽ được thực hiện hoặc không có hoạt động nào được thực hiện ( tất cả hoặc không có gì ). C – Consistency – tính nhất quán là thuộc tính đảm bảo rằng mỗi giao dịch thành công chỉ ghi lại kết quả hợp lệ. Nghĩa là, đây là sự đảm bảo rằng trong trường hợp giao dịch thành công, tất cả các quy tắc và hạn chế mà hệ thống áp đặt đối với dữ liệu cụ thể sẽ được đáp ứng, nếu không giao dịch sẽ không được hoàn thành và dữ liệu trong hệ thống sẽ trở về trạng thái trước đó. tình trạng. I - Isolation - cách ly là thuộc tính cho biết trong quá trình thực hiện một giao dịch, các giao dịch song song sẽ không ảnh hưởng đến kết quả của giao dịch đó. Thuộc tính này tiêu tốn nhiều tài nguyên nên nó thường được thực hiện một phần bằng cách cho phép các mức cách nhiệt nhất định giải quyết các vấn đề cách nhiệt nhất định. Chúng ta sẽ thảo luận vấn đề này chi tiết hơn trong câu hỏi tiếp theo. D - Độ bền - thuộc tính này đảm bảo rằng nếu người dùng nhận được xác nhận từ hệ thống rằng giao dịch đã được hoàn thành, anh ta có thể chắc chắn rằng những thay đổi mình đã thực hiện sẽ không bị hủy do một số lỗi. Nghĩa là, bạn có thể chắc chắn rằng một số loại lỗi hệ điều hành sẽ không ảnh hưởng gì đến dữ liệu của bạn nếu bạn đã nhận được xác nhận hoàn tất thành công giao dịch của mình.82. Mức độ cô lập giao dịch là gì?
Như tôi đã nói trước đó, việc cung cấp cách ly ACID là một quá trình tốn nhiều tài nguyên. Vì vậy, tính chất này được thỏa mãn một phần. Có nhiều mức độ cách ly khác nhau và mức độ càng cao thì tác động đến năng suất càng lớn. Trước khi chuyển sang các mức cô lập giao dịch, chúng ta cần xem xét các vấn đề khác nhau của việc cô lập giao dịch không đủ :-
đọc ảo - khi cùng một mẫu (cùng một truy vấn) được gọi lặp đi lặp lại trong cùng một giao dịch, dữ liệu nhận được sẽ khác nhau, xảy ra do giao dịch khác chèn dữ liệu;
-
đọc không lặp lại - khi cùng một mẫu (cùng một truy vấn) được gọi nhiều lần trong cùng một giao dịch, dữ liệu nhận được sẽ khác nhau, xảy ra do thay đổi (cập nhật) và xóa dữ liệu bởi một giao dịch khác;
-
đọc bẩn - quá trình đọc dữ liệu được thêm hoặc thay đổi bởi một giao dịch mà sau đó không được xác nhận (được khôi phục), tức là. đọc dữ liệu không hợp lệ;
-
mất cập nhật - khi các giao dịch khác nhau thay đổi cùng một dữ liệu cùng một lúc, tất cả các thay đổi ngoại trừ thay đổi cuối cùng đều bị mất (gợi nhớ đến vấn đề “điều kiện đua” trong môi trường đa luồng).
Mức độ cách ly | Đọc ma | Đọc không lặp lại | đọc bẩn | Mất bản cập nhật |
---|---|---|---|---|
Có thể tuần tự hóa | + | + | + | + |
ĐỌC LẶP LẠI | - | + | + | + |
ĐỌC CAM KẾT | - | - | + | + |
ĐỌC KHÔNG CAM KẾT | - | - | - | + |
KHÔNG CÓ | - | - | - | - |
83. Sự khác biệt giữa Tuyên bố và Chuẩn bị là gì?
Và ở đây quá trình chuyển đổi sang các tính năng của công nghệ JDBC không được suôn sẻ cho lắm . Vì vậy, trước tiên, hãy tìm hiểu Statement thực sự là gì . Đây là một đối tượng được sử dụng để tạo các truy vấn SQL. JDBC sử dụng ba loại - Statement , PreparedStatement và CallableStatement . Hôm nay chúng ta sẽ không xem xét CallableStatement : hãy nói về sự khác biệt giữa Statement và preparedStatement .-
Câu lệnh được sử dụng để thực thi các truy vấn SQL đơn giản mà không cần chèn các tham số được chèn động. Chuẩn bị được sử dụng với khả năng chèn động các tham số đầu vào.
-
Để đặt tham số trong ReadyStatement, tham số đầu vào trong yêu cầu được viết dưới dạng dấu chấm hỏi, do đó, sau đó có thể chèn một giá trị bằng cách sử dụng nhiều bộ cài đặt khác nhau, chẳng hạn như setDouble() , setFloat() , setInt() , setTime() ... . Kết quả là bạn sẽ không chèn sai loại dữ liệu vào truy vấn của mình.
-
preparedStatement được "biên dịch trước" và sử dụng bộ nhớ đệm, do đó việc thực thi nó có thể nhanh hơn một chút so với truy vấn từ các đối tượng Statement . Kết quả là, các truy vấn SQL được thực thi thường xuyên sẽ được viết dưới dạng đối tượng preparedStatement để cải thiện hiệu suất .
-
Câu lệnh dễ bị tấn công bởi SQL SQL, trong khi Chuẩn bị sẵn sàng ngăn chặn chúng. Đọc thêm về cách loại bỏ việc chèn SQL và các phương pháp hay nhất khác về bảo mật Java trong bài viết này .
GO TO FULL VERSION