CodeGym /Blog Java /Ngẫu nhiên /Khám phá các câu hỏi và câu trả lời từ cuộc phỏng vấn xin...
John Squirrels
Mức độ
San Francisco

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 3

Xuất bản trong nhóm
CHÀO! Cũng như không thể học cách lái máy bay nếu không được đào tạo đặc biệt, bạn không thể trở thành nhà phát triển Java nếu không dành nhiều thời gian để nghiên cứu các nền tảng lý thuyết cần thiết. Và đó chính xác là những gì chúng ta sẽ làm hôm nay: chúng ta sẽ tiếp tục khám phá các câu hỏi gặp phải trong các cuộc phỏng vấn việc làm dành cho nhà phát triển Java và tất nhiên, chúng ta sẽ xem xét các câu trả lời. Dưới đây là phần đầu tiên và phần thứ hai của tổng quan này. Không còn nghi ngờ gì nữa, bạn có thể trở thành một nhà phát triển Java giỏi mà không cần phải trả lời tất cả những câu hỏi này. Điều đó có nghĩa là, nếu bạn hiểu rõ tất cả những điều phức tạp của Java, bạn chắc chắn sẽ có lợi thế và trông hấp dẫn hơn trong mắt nhà tuyển dụng tương lai. 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 3 - 1

20. Yếu tố nào của ngôn ngữ cho phép đóng gói?

Hãy nhớ lại rằng đóng gói là ẩn đi các chi tiết triển khai của một lớp. Nói cách khác, khi lớp của chúng ta được sử dụng, người ngoài không thể thấy rõ các bộ phận bên trong và logic bên trong của nó. Và những yếu tố nào của ngôn ngữ chịu trách nhiệm cho điều này? Tất nhiên là truy cập các công cụ sửa đổi ! Bất cứ điều gì chúng tôi cần ẩn, chúng tôi đánh dấu bằng công cụ sửa đổi riêng tư . Ví dụ: các trường riêng tư của một lớp hoặc một số phương thức nội bộ giúp triển khai một số chức năng nội bộ. Và đối với bất kỳ nội dung nào mà chúng tôi muốn cung cấp quyền truy cập bên ngoài, chúng tôi sẽ thêm công cụ sửa đổi quyền truy cập công khai . Ví dụ: một phương thức triển khai một số chức năng (có thể sử dụng nội bộ nhiều phương thức riêng tư) hoặc tất nhiên là các getters và setters để truy cập vào các trường riêng tư của một lớp. Chúng tôi chưa đề cập đến các công cụ sửa đổi mặc địnhđược bảo vệ , những công cụ này có thể được sử dụng linh hoạt hơn và tùy chỉnh cụ thể hơn quyền truy cập vào các phần nhất định của lớp.

21. Những yếu tố nào của ngôn ngữ cho phép kế thừa?

Kế thừa là một cơ chế cho phép bạn tạo các lớp dựa trên một lớp khác. Java có từ khóa mở rộng cho việc này. Ví dụ: giả sử chúng ta có lớp Cat và muốn tạo lớp con Lion . Trong mã, nó sẽ trông giống như thế này:

public class Lion extends Cat
Và điều này có nghĩa là lớp Lion kế thừa tất cả các phương thức và biến của lớp Cat , ngoại trừ các biến tĩnh. Một thành phần khác của ngôn ngữ chịu trách nhiệm kế thừa là super . Nó là một tài liệu tham khảo tương tự như thế này . Từ khóa this đề cập đến đối tượng mà nó được tham chiếu. Từ khóa super đề cập đến cha mẹ của đối tượng hiện tại. Thông thường super được sử dụng:
  1. Để gọi hàm tạo của một siêu lớp. Ví dụ: lớp Cat có một biến tên nội bộ phải được khởi tạo trong hàm tạo. Trong hàm tạo của lớp Lion , nó sẽ trông như thế này:

    
    public Lion(final String name) {
       super(name);
    }

  2. Để tham khảo các trường và phương thức của cha mẹ. Ví dụ: trong lớp Cat , chúng ta có trường tuổi được khởi tạo :

    
    public class Cat {
       int age = 10;

Nhưng chúng tôi có cùng trường khởi tạo trong Lion :

public class Lion extends Cat {
   int age = 15;
Và nếu trong một đối tượng Lion , chúng ta muốn tham chiếu đến biến age của đối tượng cha, thì chúng ta phải thực hiện điều đó thông qua super :

super.name

22. Yếu tố nào của ngôn ngữ tạo nên tính đa hình?

Đa hình là khả năng của một đối tượng có một chữ ký có nhiều dạng (nhiều cách triển khai). 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 3 - 2Chúng tôi có thể tự tin tuyên bố rằng các từ khóa triển khaimở rộng của Java chịu trách nhiệm về tính đa hình. Khi chúng ta có một giao diện, các công cụ cho phép chúng ta cung cấp một cách triển khai khả thi, nhưng đó không nhất thiết phải là cách triển khai duy nhất, phải không? Chúng ta hãy xem lại việc sử dụng các công cụ trông như thế nào :

public class Cat implements Animal
Sau đó, trong lớp Cat , chúng ta phải triển khai tất cả các phương thức trừu tượng trong giao diện Animal . Tính kế thừa cũng vậy: trong lớp con, chúng ta có thể ghi đè cách triển khai hiện có của một phương thức. Điều này có nghĩa là với nhiều lớp con, chúng ta có thể có nhiều phần ghi đè khác nhau của cùng một phương thức. Hoặc một siêu lớp có thể trừu tượng và có một phương thức nhất định phải được triển khai theo một cách đặc biệt trong mỗi lớp con của nó. Nói cách khác, phương pháp này sẽ có nhiều cách thực hiện khác nhau. Chú thích @Override cũng có thể giúp chúng ta điều này. Nó được đặt phía trên các phương thức đã triển khai và cho biết rằng chúng ta muốn triển khai hoặc ghi đè (nếu việc triển khai đã tồn tại trong siêu lớp) một phương thức cụ thể của siêu lớp hoặc giao diện. Nó là tùy chọn và giúp phát hiện lỗi dễ dàng hơn. Bạn sử dụng chú thích này để báo cho trình biên dịch biết rằng bạn muốn ghi đè/triển khai phương thức siêu lớp/giao diện. Trình biên dịch sau đó sẽ đảm bảo rằng bạn không mắc lỗi trong chữ ký phương thức.

23. RẮN là gì? Cung cấp ví dụ

SOLID là từ viết tắt của năm nguyên tắc thiết kế OOP cơ bản của Robert Martin. S (Nguyên tắc trách nhiệm đơn) : quy định rằng một lớp chỉ nên có một mục đích/trách nhiệm. Nói cách khác, bạn không nên tạo các lớp làm được mọi việc. Nếu làm vậy, bạn có thể tái tạo mô hình phản đối "God Object". Nếu bạn có một đối tượng Cat , thì nó chỉ nên có các phương thức để tương tác với chức năng bên trong của nó, nhưng nó không được chứa bất kỳ logic nghiệp vụ nào không liên quan đến phiên bản đó. Ví dụ, một số cơ chế lưu trữ các đối tượng thuộc loại này. Chức năng này (bên ngoài thực thể của Cat ) nên được chuyển sang các lớp hoặc dịch vụ khác, có nhiệm vụ cung cấp logic nghiệp vụ cho các đối tượng tương ứng. O (Nguyên tắc đóng mở) : Nguyên tắc này được mô tả như sau: các thực thể phần mềm (lớp, mô-đun, chức năng, v.v.) phải mở để mở rộng nhưng đóng để sửa đổi. Ví dụ: giả sử chúng ta cần chức năng tương tự nhưng hơi khác so với chức năng của lớp Cat hiện tại . Thay vì thay đổi chức năng của lớp Cat và do đó phá vỡ mã ở mọi nơi nó đã được sử dụng, chúng ta có thể sử dụng tính kế thừa hoặc thành phần . Do đó, chúng tôi đạt được mục tiêu sửa đổi chức năng của lớp Cat và chúng tôi làm như vậy mà không thay đổi chính lớp đó cũng như không vi phạm bất kỳ điều gì. L (Nguyên tắc thay thế Liskov) : đây là nguyên tắc thay thế của Barbara Liskov. Nguyên tắc nói rằng một hàm lấy loại cơ sở sẽ có thể sử dụng các kiểu con của loại cơ sở đó mà không cần biết điều gì đang xảy ra. Ví dụ: lớp Cat của chúng ta có thể được thay thế bởi bất kỳ lớp con cháu nào của nó, chẳng hạn như Lion , mà không thay đổi về cơ bản hành vi của nó. Logic (hành vi) chung vẫn giữ nguyên, nhưng chi tiết triển khai chức năng cụ thể sẽ thay đổi. I (Nguyên tắc phân chia giao diện) : nguyên tắc này nêu rõ rằng tốt hơn là nên có nhiều giao diện chuyên biệt (tập trung hẹp) hơn là một giao diện phổ quát. Ví dụ: giả sử một nhà phát triển triển khai một số giao diện. Họ chỉ cần một trong các phương thức của nó, nhưng giao diện có thêm chín phương thức không liên quan đến logic của phương thức được yêu cầu. Trong trường hợp này, nhà phát triển sẽ cần triển khai mười phương thức giao diện, chín trong số đó là không cần thiết đối với họ! Thay vào đó, tốt hơn là tạo ra mười giao diện khác nhau mà bạn có thể triển khai khi cần. Chà, nếu không phải mười thì là vài, mỗi phương thức có liên quan chặt chẽ đến mục đích duy nhất của giao diện. D (Nguyên tắc đảo ngược phụ thuộc): Nguyên tắc nói rằng các mô-đun cấp cao hơn không nên phụ thuộc vào các mô-đun cấp thấp hơn. Nguyên tắc này cũng nêu rõ: "Sự trừu tượng không nên phụ thuộc vào chi tiết. Chi tiết nên phụ thuộc vào sự trừu tượng." Chúng ta phải xây dựng logic của mình bằng cách tham khảo các giao diện và chuyển qua các đối tượng cụ thể của các lớp triển khai giao diện được yêu cầu. Ví dụ: giả sử chúng ta có giao diện Cat và một số triển khai, chẳng hạn như LionHouseCat . Chúng tôi xây dựng logic cụ thể của mình để tương tác với giao diện Cat . Sau đó, chúng tôi chỉ thay thế giao diện bằng cách triển khai cụ thể ( Lion hoặc HouseCat ), chứ không phải ngược lại.

24. Lớp, đối tượng và giao diện là gì?

Chúng ta sẽ nhớ lại rằng Java là một ngôn ngữ OOP. Tức là các chương trình Java được xây dựng dựa trên sự tương tác giữa các đối tượng. Một chương trình giống như một tổ kiến, trong đó mỗi con kiến ​​là một vật thể. 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 3 - 3Đối tượng là tập hợp dữ liệu bao gồm nhiều phương thức (hàm) khác nhau để tương tác với dữ liệu nội bộ này. Lớp là các hướng dẫn hoặc mẫu để tạo đối tượng. Điều này có nghĩa là chúng ta có thể có nhiều đối tượng được xây dựng theo cùng một hướng dẫn nhưng chứa dữ liệu khác nhau (hoặc giống nhau). Lấy ví dụ từ cuộc sống thực, chúng ta có thể nói rằng lớp là bản thiết kế của một tòa nhà và đối tượng là một tòa nhà được xây dựng cụ thể theo bản thiết kế. Giao diện tương tự như lớp, nhưng chúng ta không thể sử dụng chúng để tạo đối tượng. Mục đích của họ là thêm tính trừu tượng cho Java. Chính xác hơn, chúng tăng thêm tính linh hoạt cho mối quan hệ giữa các lớp và đối tượng. Khi nói đến tính linh hoạt, chúng tôi muốn nói đến tính đa hình và tính trừu tượng được mô tả trước đây, điều này tạo ra nhiều cơ hội để xây dựng kiến ​​trúc bên trong của ứng dụng.

25. Lớp POJO là gì? Cho một ví dụ về một lớp như vậ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 3 - 4POJO (Đối tượng Java cũ đơn giản) là một đối tượng lớp đơn giản, không kế thừa từ bất kỳ lớp cụ thể nào và không triển khai bất kỳ giao diện dịch vụ nào ngoài những giao diện cần thiết cho mô hình kinh doanh. Nói cách khác, lớp POJO chỉ là lớp không có yêu cầu đặc biệt. Yêu cầu duy nhất là không có nhiều chuông và còi khác nhau gắn liền với một khuôn khổ cụ thể. Theo quy định, các lớp này không kế thừa các lớp khác (ngoại trừ các lớp POJO trong cùng gói), không triển khai giao diện (đôi khi tạo ngoại lệ cho các giao diện điểm đánh dấu từ thư viện chuẩn như Serializable hoặc Cloneable ), không sử dụng chú thích và không phụ thuộc vào thư viện của bên thứ ba. Hãy lưu ý rằng POJO có thể có các phương thức chứa logic nghiệp vụ và hàm tạo thuộc bất kỳ loại nào. Nếu chúng tôi cho phép các chú thích không thay đổi ngữ nghĩa của lớp (tức là các chú thích mà sự vắng mặt của chúng không làm thay đổi mục đích hoặc logic của đối tượng), thì các POJO cũng có thể bao gồm các thực thể JPA và các đối tượng DTO được giải tuần tự hóa từ XML hoặc JSON , có các quy tắc là được chỉ định trong chú thích. Một điều khác cần lưu ý về các lớp POJO là bạn nên ghi đè các phương thức bằnghashCode của chúng vì điều này có thể giúp chúng hoàn thành vai trò của mình tốt hơn. Ví dụ về lớp POJO :

public class User {
   private Long id;
   private String firstName;
   private String lastName;
   private Long age;
 
   public User(final Long id, final String firstName, final String lastName, final long age) {
       this.id = id;
       this.firstName = firstName;
       this.lastName = lastName;
       this.age = age;
   }
 
   public Long getId() {
       return this.id;
   }
 
   public String getFirstName() {
       return this.firstName;
   }
 
   public String getLastName() {
       return this.lastName;
   }
 
   public Long getAge() {
       return this.age;
   }
 
   @Override
   public boolean equals(final Object o) {
       if (this == o) return true;
       if (o == null || this.getClass() != o.getClass()) return false;
       final User user = (User) o;
       return Objects.equals(this.id, user.id) &&
               Objects.equals(this.firstName, user.firstName) &&
               Objects.equals(this.lastName, user.lastName) &&
               Objects.equals(this.age, user.age);
   }
 
   @Override
   public int hashCode() {
       return Objects.hash(this.id, this.firstName, this.lastName, this.age);
   }
}

26. Một lớp có thể chứa những thành phần nào?

Một lớp có thể chứa các phần tử sau:
  • trường mẫu;
  • trường tĩnh;
  • khối khởi tạo;
  • khối khởi tạo tĩnh;
  • hàm tạo (một hàm tạo trống luôn được khai báo theo mặc định);
  • phương pháp;
  • phương pháp tĩnh;
  • các chú thích khác nhau (có thể được áp dụng cho chính lớp đó hoặc các bộ phận cấu thành của nó);
  • thuốc generic ;
  • kế thừa các lớp khác ( mở rộng ) hoặc triển khai các giao diện ( thực hiện ).

27. Hãy cho chúng tôi biết về tính kế thừa trong Java. Các chi tiết cụ thể của từ khóa siêu là gì?

Ở trên, trước đây tôi đã nói về tính kế thừa và từ khóa super trong Java. Tôi sẽ đề cập đến một vài điểm quan trọng hơn:
  1. Chúng ta chỉ có thể kế thừa một lớp duy nhất: Java không có tính đa kế thừa trong Java. Với sự ra đời của các phương thức mặc định trong Java 8, tuyên bố này sẽ gây tranh cãi rất nhiều.
  2. Các phương thức và trường riêng tư cũng được kế thừa. Đơn giản là chúng không thể được truy cập từ lớp con (nhưng chẳng hạn, nếu chúng ta có một trường riêng và có các getter và setters công khai hoặc được bảo vệ , thì chúng ta có thể sử dụng chúng để truy cập vào trường).
  3. các lớp cuối cùng không thể được kế thừa.
  4. phương thức cuối cùng không thể bị ghi đè (nhưng chúng có thể được kế thừa và nạp chồng).
  5. các phương thức và biến tĩnh không được kế thừa (vì chúng được gắn vào các lớp chứ không phải đối tượng).
  6. Khi kế thừa các lớp trừu tượng, các phương thức trừu tượng của chúng phải được triển khai hoặc lớp con cũng phải được khai báo là trừu tượng.
  7. Nếu có các hàm tạo không mặc định trong lớp cha, thì chúng phải được ghi đè trong lớp con (nhưng @Override không được viết phía trên chúng).
  8. Bạn có thể mở rộng công cụ sửa đổi truy cập sang các phương thức được ghi đè trong lớp con: riêng tư -> mặc định -> được bảo vệ -> công khai .
  9. Các phương thức được ghi đè trong lớp con có thể đưa ra các ngoại lệ hẹp hơn, ví dụ: Ngoại lệ -> IOException -> FileNotFoundException.
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 3 - 5

28. Chữ ký phương thức là gì? Cung cấp ví dụ về chữ ký đúng và sai

Chữ ký phương thức là tên của phương thức cộng với loại tham số đầu vào (thứ tự của các tham số rất quan trọng). Chữ ký phương thức không bao gồm giá trị trả về hoặc các ngoại lệ mà phương thức đưa ra. Ví dụ về chữ ký đúng:

doSomething(int, double, double)
Ví dụ về chữ ký sai:

void doSomething(int firstArg, int secondArg) throws Exception
Chữ ký phương thức, kết hợp với kiểu trả về và danh sách các ngoại lệ được ném ra, được gọi là hợp đồng phương thức . Đó là tất cả cho ngày hôm nay! Hẹn gặp lại!
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION