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ị trường STUDENT trên bảng điều khiển bằng cách gọi phương thức toString() của nó :
System.out.println(Role.STUDENT.toString());
Kết quả là chúng ta nhận được đầu ra của bàn điều khiển sau:
72. Bạn có thể khai báo hàm tạo bên trong Enum không?
Vâng tất nhiên. Hàm tạo là thứ thiết lập các giá trị của các trường bên trong của enum . Ví dụ: hãy thêm hai trường vào enum trước đó ( ageFrom và ageTo ) để chỉ ra độ 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 phổ biến nhất đối với các nhà phát triển Java tương lai. Để bắt đầu, khi so sánh các giá trị đơn giản ( int , char , double ...), chúng tôi sử dụng == , vì các biến này chứa các giá trị cụ thể có thể so sánh trực tiếp. Hơn nữa, các biến nguyên thủy không phải là các đối tượng chính thức — chúng không kế thừa lớp Object và không có phương thức Equals() . Nếu chúng ta đang nói về việc so sánh các biến tham chiếu đến các đối tượng, thì chúng ta cần biết rằng == chỉ so sánh giá trị của các tham chiếu, tức là chúng có tham chiếu đến cùng một đối tượng hay không. Ngay cả khi tất cả dữ liệu trong một đối tượng giống hệt với tất cả dữ liệu trong một đối tượng khác, việc sử dụng == để so sánh sẽ mang lại kết quả âm tính ( false ), vì chúng là các đối tượng riêng biệt. Như bạn có thể đoán, chúng tôi sử dụng phương thức Equals() để 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 và cần thiết để so sánh đầy đủ các đối tượng. Nhưng tôi cần phải nói ngay rằng để phương pháp này hoạt động chính xác, nó phải được ghi đè để chỉ ra chính xác cách so sánh các đối tượng. Nếu bạn không ghi đè phương thức thì bạn sẽ có cách triển khai mặc định để so sánh các đối tượng bằng cách sử dụng == . Trong IntelliJ IDEA, bạn có thể tự động ghi đè lên nó bằng phím tắt IDEA: Alt+Insert . Trong cửa sổ xuất hiện, chọn Equals() và hashCode() . Sau đó chọn các lĩnh vực cần tham gia. Thì đấy! Các phương pháp được thực hiện tự động. Đây là một ví dụ về cách một phương thức bằng được tạo tự động tìm kiếm lớp Cat đơn giản nhất có thể với 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);
}
Khi nói đến enum , không có sự khác biệt thực tế giữa == và Equals() . Xét cho cùng, một enum lưu trữ các hằng số và ngay cả khi chúng ta so sánh các giá trị giống hệt nhau bằng cách sử dụng == , chúng ta sẽ nhận được true , vì các tham chiếu được so sánh sẽ luôn trỏ đến cùng một đối tượng. Và việc sử dụng Equals() cũng mang lại cho chúng ta kết quả chính xác. Nếu bạn đi vào phần nội dung của phương thức bằng cho Enum , bạn sẽ thấy lớp Enum có cách triển khai như sau: Bên trong chúng ta có thể thấy một so sánh cũ của các tham chiếu! Tóm lại, đối với enum s, chúng ta có thể so sánh chính xác bằng cách sử dụng cả == và Equals() .
74. Phương thức ordinal() của Enum có tác dụng gì?
Khi chúng ta gọi phương thức int ordinal() trên trường enum , chúng ta sẽ nhận được chỉ mục dựa trên 0 của trường trong danh sách các giá trị enum. Hãy gọi phương thức này trên một trường trong Vai trò enum mà trước đây chúng tôi đã xem xét:System.out.println(Role.DIRECTOR.ordinal());
Theo đó, giao diện điều khiển hiển thị:
75. Enum có thể được sử dụng với TreeSet hoặc TreeMap trong Java không?
Chúng ta có thể sử dụng các loại enum trong TreeSet và TreeMap . Và chúng ta có thể viết điều này: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à CompareTo() của Enum có liên quan như thế nào?
Như đã đề cập trước đó, ordinal() trả về chỉ mục của trường trong danh sách các trường enum. Ngoài ra, khi xem xét câu hỏi trước, bạn đã thấy rằng khi các trường enum được đưa vào TreeSet (là một tập hợp được sắp xếp), chúng sẽ tuân theo thứ tự được khai báo trong enum . Và như chúng ta đã biết, TreeSet và TreeMap sắp xếp các mục bằng cách gọi phương thức so sánhTo() của giao diện Comparable của chúng . Điều này cho chúng ta biết rằng lớp Enum triển khai giao diện Comparable , có nghĩa là nó triển khai phương thức so sánhTo() , phương thức này sử dụng nội bộ phương thức ordinal() để xác định thứ tự sắp xếp. Đi sâu vào lớp Enum , chúng ta có thể xác nhận giả định của mình: Và đây là nội dung 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, là số chỉ mục 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ụ Enum
Trong các câu hỏi được thảo luận ở trên, tôi đã đưa ra ví dụ về enum s. Tôi thấy không có lý do gì để sao chép mã ở đây. Ví dụ: xem Câu hỏi 72 về hàm tạo trong enum.78. Enum có thể được sử dụng trong switch case không?
Nó có thể và nên như vậy! Nhìn vào kinh nghiệm của tôi, tôi sẽ lưu ý rằng một trong những cách sử dụng phổ biến nhất của enum là trong các cấu trúc logic như câu lệnh switch . Trong trường hợp này, bạn có thể cung cấp tất cả các trường hợp có thể xảy ra — khi bạn viết logic cho từng trường enum , bạn thậm chí không cần mệnh đề mặc định ! Xét cho cùng, nếu bạn sử dụng String hoặc một giá trị số, chẳng hạn như int , bạn có thể nhận được một giá trị không mong muốn, nhưng điều đó là không thể với enum . Đây là câu lệnh switch sẽ trông như thế nào trong ví dụ trên:public void doSomething(Role role) {
switch (role) {
case STUDENT:
// some logic for STUDENT
break;
case TEACHER:
// some logic for TEACHER
break;
case DIRECTOR:
// some logic for DIRECTOR
break;
case SECURITY_GUARD:
// some logic for SECURITY_GUARD
break;
}
}
79. Làm cách nào để có được tất cả các giá trị có thể có của Enum?
Nếu bạn cần lấy tất cả các giá trị enum có thể có, 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ó thể có cho enum theo thứ tự tự nhiên của chúng (nghĩa là theo thứ tự chúng được chỉ định trong enum ) . Ví dụ:Role[] roles = Role.values();
for (Role role : roles) {
System.out.println(role);
}
Chúng tôi sẽ có những điều sau đây trên bảng điều khiển:
API luồng
80. Luồng trong Java là gì?
API Java Stream là một cách tương tác tương đối mới với luồng dữ liệu, cho phép chúng tôi 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ý dữ liệu song song giữa một số luồng, có khả năng tăng hiệu suất.81. Kể tên các thuộc tính chính của giao dịch
Chủ đề ở đây là API Stream, nhưng câu hỏi là về giao dịch. Hmm... Trước tiên, hãy hiểu giao dịch là gì. Giao dịch là một nhóm các hoạt động tuần tự trên cơ sở dữ liệu. Nó đại diện cho một đơn vị công việc hợp lý. Một giao dịch có thể được thực hiện độc lập với các giao dịch đồng thời khác một cách hoàn toàn và thành công, do đó duy trì tính toàn vẹn của dữ liệu hoặc hoàn toàn không được thực hiện, trong trường hợp đó nó không có hiệu lực. Giao dịch có bốn thuộc tính chính mà chúng ta có thể dễ dàng ghi nhớ nhờ từ viết tắt ACID . Chúng ta hãy xem từng chữ cái trong từ viết tắt này có nghĩa là gì: A là viết tắt của Atomicity . Thuộc tính này đảm bảo rằng không có giao dịch nào được cam kết một phần trong hệ thống. Tất cả các thao tác con của nó sẽ được thực thi hoặc không có thao tác nào trong số chúng sẽ được thực thi ( tất cả hoặc không có gì ). С là viết tắt của Tính nhất quán . Thuộc tính này đảm bảo rằng mỗi giao dịch thành công sẽ chỉ có kết quả hợp lệ. Nói cách khác, đây là sự đảm bảo rằng nếu giao dịch thành công thì tất cả các quy tắc của hệ thống đối với dữ liệu cụ thể sẽ được tuân theo. Nếu giao dịch không thành công thì nó sẽ không được thực thi và dữ liệu của hệ thống sẽ trở về trạng thái trước đó. Tôi là viết tắt của Sự cô lập . Thuộc tính này có nghĩa là khi một giao dịch được thực hiện, các giao dịch đồng thời không được ảnh hưởng đến kết quả của nó. Thuộc tính này sử dụng nhiều tài nguyên, do đó, theo quy định, nó được triển khai một phần, cho phép các mức cách ly nhất định giúp giải quyết các vấn đề cách ly cụ thể. 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 là viết tắt của Độ 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 rằng giao dịch đã hoàn thành thì họ có thể chắc chắn rằng các thay đổi 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ố 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 rằng giao dịch của bạn đã hoàn tất thành công.82. Mức độ cô lập giao dịch là gì?
Như tôi đã nói trước đó, khi nói đến thuộc tính ACID, việc đảm bảo cách ly là một quá trình tiêu tốn nhiều tài nguyên. Theo đó, tài sản này được thực hiện một phần. Có nhiều mức độ cô lập khác nhau: cấp độ càng cao thì tác động đến hiệu suất càng nghiêm trọng. 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 xảy ra do cách ly giao dịch không đủ :-
đọc ảo : khi cùng một yêu cầu, được gọi nhiều lần trong một giao dịch, mang lại kết quả khác nhau do được chèn bởi một giao dịch khác;
-
lần đọc không thể lặp lại : khi cùng một yêu cầu, được gọi nhiều lần trong một giao dịch, mang lại dữ liệu khác nhau do thay đổi (cập nhật) và xóa bởi giao dịch khác;
-
đọc bẩn : đọc dữ liệu chưa được cam kết đã được thêm hoặc sửa đổi bởi một giao dịch và sau đó được khôi phục;
-
mất cập nhật : khi một khối dữ liệu bị thay đổi đồng thời bởi các giao dịch khác nhau và tất cả các thay đổi ngoại trừ thay đổi cuối cùng đều bị mất (tương tự như điều kiện chạy đua trong đa luồng).
Mức độ cách ly | ma đọc | Số lần đọc không thể 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à Tuyên bố đã chuẩn bị là gì?
Ở đây chúng tôi đã đột ngột thay đổi chuyển sang các tính năng của JDBC . Trong mọi trường hợp, trước tiên chúng ta hãy tìm hiểu Tuyên bố là gì. Nó 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 . Thay vào đó, chúng ta đang 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 tham số đầu vào thời gian chạy. Chuẩn bị có thể chấp nhận các tham số đầu vào khi chạy.
-
Để đặt tham số cho ReadyStatement , tham số đầu vào được viết dưới dạng dấu chấm hỏi trong yêu cầu, do đó chúng có thể được thay thế bằng một số giá trị bằng cách sử dụng nhiều setters khác nhau, chẳng hạn như setDouble() , setFloat() , setInt() , setTime() ... Điều này có nghĩa là bạn sẽ không chèn sai loại dữ liệu vào yêu cầu.
-
Chuẩn bị sẵn sàng được biên dịch trước và sử dụng bộ nhớ đệm, do đó, nó có thể được thực thi nhanh hơn một chút so với yêu cầu được thực hiện từ các đối tượng Tuyên bố . Kết quả là, các câu lệnh SQL được thực thi thường xuyên sẽ được tạo dưới dạng đối tượng Chuẩn bị sẵn sàng để cải thiện hiệu suất.
-
Câu lệnh dễ bị tấn công bởi SQL SQL, nhưng preparedStatement ngăn chặn chúng.
GO TO FULL VERSION