Thực hành hay lý thuyết? Điều gì quan trọng hơn? Nhiều người sẽ tự nhiên nói rằng thực hành là quan trọng hơn. Giống như, hãy luyện tập cho đến khi mặt trời lặn và bạn sẽ thấy hạnh phúc. Tôi sẽ dám không đồng ý với điều này. Khám phá các câu hỏi và câu trả lời từ cuộc phỏng vấn xin việc cho vị trí nhà phát triển Java.  Phần 8 - 1Trong các cuộc phỏng vấn, sẽ không ai biết bạn ngầu như thế nào khi luyện tập. Thay vào đó, bạn sẽ được yêu cầu chứng minh lý thuyết của mình. Phải đến sau này, khi bạn đã vượt qua tất cả các lớp phỏng vấn và được giao cho một dự án, bạn mới áp dụng được các kỹ năng thực tế của mình. Bạn có thể phản đối, nói rằng đôi khi họ giao cho bạn một bài kiểm tra nên vẫn cần thực hành. Tôi không đồng ý, nhưng quan điểm của tôi là THÔI KHI, nhưng bạn LUÔN cần thể hiện kiến ​​thức về lý thuyết trong một cuộc phỏng vấn. Bạn có cảm thấy sự khác biệt? Tất cả điều này có nghĩa là bạn phải có một nền tảng lý thuyết vững chắc dưới chân mình và đó là những gì chúng ta sẽ tiếp tục xây dựng ngày hôm nay. Cụ thể hơn, chúng ta sẽ tiếp tục xem xét các câu hỏi thường được hỏi trong các cuộc phỏng vấn.

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:
HỌC SINH
Vì vậy, chúng ta thấy rằng đối với một enum , việc triển khai mặc định của toString() sẽ trả về tên của chính hằng số đó.

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 đó ( ageFromageTo ) để 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()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 ageString 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 ==Equals() . Khám phá các câu hỏi và câu trả lời từ cuộc phỏng vấn xin việc cho vị trí nhà phát triển Java.  Phần 8 - 2Xé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: Khám phá các câu hỏi và câu trả lời từ cuộc phỏng vấn xin việc cho vị trí nhà phát triển Java.  Phần 8 - 3Bê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ả ==Equals() . Khám phá các câu hỏi và câu trả lời từ cuộc phỏng vấn xin việc cho vị trí nhà phát triển Java.  Phần 8 - 4

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ị:
2

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 TreeSetTreeMap . 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ị:
SINH VIÊN GIÁO VIÊN GIÁM ĐỐC AN NINH_GUARD
Chúng tôi đã nhận được kết quả nhưng không theo thứ tự bảng chữ cái. Vấn đề là nếu chúng ta sử dụng các trường enum làm giá trị TreeSet hoặc làm khóa TreeMap , thì các trường đó sẽ được sắp xếp theo thứ tự tự nhiên của chúng (theo thứ tự chúng được chỉ định trong enum ) . Hiểu rằng đây là cách nó hoạt động sẽ giúp chúng ta viết mã tốt hơn.

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, TreeSetTreeMap 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: Khám phá các câu hỏi và câu trả lời từ cuộc phỏng vấn xin việc cho vị trí nhà phát triển Java.  Phần 8 - 5Và đây là nội dung của chính phương thức: Khám phá các câu hỏi và câu trả lời từ cuộc phỏng vấn xin việc cho vị trí nhà phát triển Java.  Phần 8 - 6Phươ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ám phá các câu hỏi và câu trả lời từ cuộc phỏng vấn xin việc cho vị trí nhà phát triển Java.  Phần 8 - 7 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:
SINH VIÊN GIÁO VIÊN GIÁM ĐỐC AN NINH_GUARD

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).

Khi điều đó xảy ra, các mức độ cô lập giao dịch được đặc trưng bởi những vấn đề cô lập mà chúng bảo vệ chống lại. Hãy xem xét bảng mức độ cách ly sau đây và các vấn đề mà chúng bảo vệ chống lại:
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Ó - - - -
Và đừng quên mặt trái của nó: mức độ cô lập càng cao thì thời gian xử lý các giao dịch càng lâu (do việc thực hiện song song nhiều giao dịch).

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 , PreparedStatementCallableStatement . 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 StatementpreparedStatement .
  1. 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.

  2. Để đặ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.

  3. 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.

  4. Câu lệnh dễ bị tấn công bởi SQL SQL, nhưng preparedStatement ngăn chặn chúng.

Và với điều đó, chúng ta sẽ gọi nó là một ngày!