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 6

Xuất bản trong nhóm
Chào thế giới! Điều cần thiết đối với bất kỳ nhà phát triển nào là không bao giờ ngừng phát triển. Suy cho cùng, nếu bạn dừng lại, bạn có nguy cơ bị mất nhu cầu và hoàn toàn bị loại khỏi thị trường việc làm. Thế giới CNTT không ngừng phát triển và tiến về phía trước - bạn cần phải di chuyển cùng với nó. Nhưng đồng thời, bạn không thể lúc nào cũng sử dụng những công nghệ mới nhất kẻo quên mất những "kinh điển" (các chủ đề phát triển phần mềm cổ điển). Hôm nay tôi muốn tiếp tục thảo luận về "các chủ đề cổ điển" dành cho các nhà phát triển Java. 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 6 - 1Tôi sẽ chỉ ra rằng câu trả lời của tôi không phải là lời cuối cùng. Đó chỉ là quan điểm của tôi về những câu trả lời đúng - bạn có thể không đồng ý với một số câu trả lời. Điều đó là tốt, vì vậy hãy thoải mái chia sẻ ý kiến ​​​​của bạn trong phần bình luận. Bạn có thể tìm thấy liên kết đến các phần trước của bài đánh giá ở cuối bài viết. 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 6 - 2

Thư viện và tiêu chuẩn

52. Ngủ đông là gì? Sự khác biệt giữa JPA và Hibernate là gì?

Để trả lời câu hỏi này, tôi nghĩ trước tiên chúng ta cần hiểu JPA là gì. Nó là một đặc tả mô tả ánh xạ quan hệ đối tượng của các đối tượng Java đơn giản và cung cấp API để lưu trữ, truy xuất và thao tác các đối tượng đó. Nghĩa là, cơ sở dữ liệu quan hệ (DB) được biểu diễn dưới dạng tập hợp các bảng được kết nối với nhau. Và JPA là một tiêu chuẩn được áp dụng rộng rãi, mô tả cách các đối tượng có thể tương tác với cơ sở dữ liệu quan hệ. Như bạn có thể thấy, JPA là một cái gì đó trừu tượng và vô hình. Nó giống như ý tưởng, cách tiếp cận. 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 6 - 3Nhưng Hibernate là một thư viện cụ thể triển khai các mô hình JPA. Nói theo thứ tự, bạn có thể sử dụng thư viện này để làm việc với cơ sở dữ liệu quan hệ thông qua các đối tượng biểu diễn dữ liệu trong cơ sở dữ liệu (Thực thể). Thư viện này được cho là rất gần với lý tưởng của JPA. Đó có thể là lý do tại sao nó trở nên phổ biến. Như bạn có thể tưởng tượng, sự phổ biến của nó đã chứng minh cho sự phát triển và cải tiến hơn nữa. Ngoài ra, việc sử dụng rộng rãi bắt nguồn từ một cộng đồng rộng lớn đã khám phá mọi câu hỏi có thể và không thể liên quan đến công cụ này. Hibernate đã được nghiên cứu kỹ lưỡng và hóa ra là nó đáng tin cậy. Có lý do chính đáng tại sao ngay cả việc triển khai JPA lý tưởng trong Spring cũng thường sử dụng Hibernate một cách ẩn giấu.

53. Xếp tầng là gì? Nó được sử dụng như thế nào trong Hibernate?

Như tôi đã nói trước đó, giao tiếp trong Hibernate diễn ra thông qua các đối tượng dữ liệu được gọi là thực thể. Các thực thể này đại diện cho các bảng cụ thể trong cơ sở dữ liệu và như bạn sẽ nhớ lại, các lớp Java có thể chứa các tham chiếu đến các lớp khác. Những mối quan hệ này cũng được phản ánh trong cơ sở dữ liệu. Theo quy định, chúng là khóa ngoại (đối với các mối quan hệ OneToOne, OneToMany, ManyToOne) hoặc các bảng trung gian (đối với các mối quan hệ ManyToMany). Khi thực thể của bạn có tham chiếu đến các thực thể liên quan khác, chú thích sẽ được đặt phía trên các tham chiếu này để biểu thị loại mối quan hệ: @OneToOne, @OneToMany, @ManyToOne, @ManyToMany. Bạn có thể chỉ định loại phân tầng cho mối quan hệ này trong thuộc tính phân tầng của chú thích. JPA có các phương thức cụ thể để tương tác với các thực thể (kiên trì, lưu, hợp nhất ...). Các kiểu xếp tầng được sử dụng để hiển thị cách hoạt động của dữ liệu liên quan; những phương pháp này được sử dụng trên một thực thể mục tiêu. Vậy chiến lược xếp tầng (loại xếp tầng) là gì? Tiêu chuẩn JPA cung cấp việc sử dụng sáu loại tầng:
  • KIÊN TRÌ - các hoạt động lưu xảy ra theo tầng (đối với các phương thức save()Persist() ). Nói cách khác, nếu chúng ta lưu một thực thể được liên kết với các thực thể khác thì các thực thể đó cũng được lưu trong cơ sở dữ liệu (nếu chúng chưa có ở đó)

  • MERGE - các hoạt động cập nhật xảy ra theo tầng (đối với phương thức merge() )

  • XÓA - các thao tác xóa xảy ra theo tầng ( phương thức Remove() )

  • TẤT CẢ - chứa ba thao tác xếp tầng cùng một lúc - KIÊN TRÌ - HỢP NHẤT - XÓA

JPA có khái niệm về một thực thể liên tục - một thực thể được liên kết với dữ liệu của nó trong cơ sở dữ liệu và được kiểm soát bởi phiên (kết nối) hiện tại. Nếu bạn thay đổi nó mà không lưu các thay đổi vào cơ sở dữ liệu thì dữ liệu của thực thể trong cơ sở dữ liệu sẽ vẫn bị thay đổi.
  • DETACH - các thực thể liên quan không được quản lý bởi phiên ( phương thức Detach() ). Tức là khi dữ liệu của các thực thể liên quan thay đổi, dữ liệu trong cơ sở dữ liệu không được cập nhật tự động - chúng được chuyển đổi từ Persistent sang Det Riêng (tức là thực thể không được JPA quản lý)

  • LÀM MỚI - mỗi khi một thực thể được làm mới với dữ liệu từ cơ sở dữ liệu ( Refresh() - làm mới các đối tượng tách rời), các thực thể liên quan của nó cũng được làm mới. Ví dụ: bằng cách nào đó bạn đã thay đổi dữ liệu được lấy từ cơ sở dữ liệu và bạn muốn khôi phục các giá trị ban đầu. Trong trường hợp này, bạn sẽ thấy thao tác này hữu ích.

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 6 - 4Hibernate hỗ trợ tất cả các hoạt động xếp tầng tiêu chuẩn này và cũng giới thiệu ba hoạt động riêng:
  • REPLICATE - được sử dụng khi chúng tôi có nhiều nguồn dữ liệu và chúng tôi muốn dữ liệu được đồng bộ hóa (phương pháp sao chép của Hibernate). Tất cả các thực thể phải có số nhận dạng (id) để đảm bảo rằng chúng có thể được tạo mà không gặp vấn đề gì (để đảm bảo rằng cùng một thực thể không có id khác nhau cho các cơ sở dữ liệu khác nhau)

  • SAVE_UPDATE - lưu/xóa xếp tầng (đối với phương thức saveOrUpdate của Hibernate )

  • LOCK - ngược lại với hoạt động DETACHED : chuyển đổi một thực thể tách rời trở lại trạng thái liên tục, tức là phiên hiện tại sẽ theo dõi thực thể đó một lần nữa

Nếu không có loại tầng nào được chọn thì một thao tác trên thực thể sẽ không ảnh hưởng đến các thực thể khác được liên kết với nó.

54. Một lớp Thực thể có thể trừu tượng được không?

Theo 2.1 Lớp thực thể của đặc tả JPA , " Cả hai lớp trừu tượng và cụ thể đều có thể là thực thể. " Vì vậy, câu trả lời là có, một lớp trừu tượng có thể là một thực thể và có thể được đánh dấu bằng chú thích @Entity.

55. Người quản lý thực thể là gì? Nó chịu trách nhiệm về việc gì?

Trước hết, tôi muốn lưu ý rằng EntityManager là thành phần quan trọng của JPA . Nó được sử dụng để tương tác giữa các thực thể với cơ sở dữ liệu. Nói chung, các phương thức tương tác của thực thể với cơ sở dữ liệu được gọi trên thực thể (kiên trì, hợp nhất, xóa, tách)... Nhưng tôi cũng lưu ý rằng thành phần này thường không phải là thành phần đơn lẻ cho toàn bộ ứng dụng. Nó thường nhẹ, một cái sẽ bị xóa và một cái mới được tạo bằng cách sử dụng EntityManagerFactory . Nếu chúng ta so sánh với JDBC , trong đó EntityManagerFactory tương tự như DataSource thì EntityManager tương tự như Connection . Trước đó, tôi đã đề cập rằng thực thể liên tục là thực thể được quản lý bởi kết nối hiện tại. Thực thể này được quản lý bởi EntityManager , có liên quan chặt chẽ với kết nối hiện tại và TransactionManager , chịu trách nhiệm mở/đóng giao dịch. Trong hình bên dưới, bạn có thể thấy vòng đời của thực 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 6 - 5EntityManager quản lý thực thể khi nó ở giai đoạn Được quản lý (khi nó tồn tại liên tục, vì nó có kết nối với EntityManager ) . Tức là nó không mới và cũng không bị loại bỏ. Khi một thực thể mới hoặc bị xóa, chúng ta có thể nói rằng nó cũng bị tách rời vì EntityManager không quản lý nó. Có các chiến lược khác nhau cho EntityManager . Bạn có thể có một đơn vị EntityManager cho toàn bộ ứng dụng hoặc tạo một đơn vị mới mỗi lần cho mỗi kết nối. Nếu bạn đang sử dụng Spring, việc tạo/xóa EntityManager sẽ được quản lý tự động một cách tự động (nhưng điều đó không có nghĩa là bạn không thể tự tùy chỉnh nó ^^). Tôi cần đề cập rằng một hoặc nhiều EntityManager tạo thành một bối cảnh bền vững . Bối cảnh liên tục là môi trường trong đó các phiên bản của thực thể được đồng bộ hóa với các thực thể tương tự trong cơ sở dữ liệu (như tôi đã nói, điều này chỉ hoạt động đối với các thực thể liên tục). Nếu bạn tìm hiểu sâu hơn về JPA (mà tôi thực sự khuyên bạn nên sử dụng), bạn sẽ rất thường xuyên gặp phải khái niệm này.

56. Lớp Assert là gì? Tại sao nó được sử dụng?

Tôi chưa từng nghe nói về một lớp như vậy trong JPA , vì vậy tôi sẽ cho rằng câu hỏi này đề cập đến một lớp được tìm thấy trong thư viện JUnit được sử dụng cho các bài kiểm tra đơn vị. Trong thư viện này, lớp Assert được sử dụng để kiểm tra kết quả thực thi mã (ở đây khẳng định có nghĩa là xác nhận rằng bạn có trạng thái/dữ liệu cụ thể tại một vị trí cụ thể trong mã). Ví dụ: giả sử bạn đang thử nghiệm một phương pháp được cho là tạo ra một con mèo. Bạn chạy phương thức và bạn nhận được một số kết quả:
Cat resultOfTest = createCat();
Nhưng bạn cần chắc chắn rằng nó được tạo chính xác, phải không? Vì vậy, bạn tạo thủ công một con mèo cụ thể ( expectedCat ) với chính xác các tham số mà bạn mong đợi thấy ở con mèo thu được từ phương thức createCat() . Sau đó bạn sử dụng lớp Assert để xác minh kết quả:
Assert.assertEquals(resultOfTest, expectedCat);
Nếu những con mèo khác nhau thì AssertionError sẽ được ném ra, điều này cho chúng ta biết rằng chúng ta không nhận được kết quả như mong đợi. Lớp Assert có nhiều phương thức khác nhau bao gồm nhiều thao tác hữu ích trong việc xác minh kết quả mong đợi. Dưới đây là một vài trong số họ:
  • khẳng địnhTrue(<boolean>) - giá trị được truyền vào dưới dạng đối số được mong đợi là đúng

  • khẳng địnhFalse(<boolean>) - giá trị được truyền vào dưới dạng đối số dự kiến ​​là sai

  • khẳng địnhNotEquals(<object1>, <object2>) - các đối tượng được truyền dưới dạng đối số phải khác nhau khi so sánh bằng cách sử dụng bằng ( false )

  • khẳng địnhThrows(<ClassNameOfException>.class, <ExceptionObject>) — đối số thứ hai dự kiến ​​sẽ là một ngoại lệ do đối số thứ nhất đưa ra (tức là đối số thứ hai thường là một lệnh gọi phương thức sẽ đưa ra một ngoại lệ của loại được yêu cầu)

Sợi dây

57. Mô tả lớp String của Java

Chuỗi là một lớp Java tiêu chuẩn chịu trách nhiệm lưu trữ và thao tác các giá trị chuỗi (chuỗi ký tự). Nó là một lớp bất biến (tôi đã viết về bất biến trước đây ở đây ), tức là dữ liệu của các đối tượng của lớp này không thể thay đổi sau khi chúng được tạo. Tôi muốn lưu ý ngay rằng các lớp StringBuilderStringBuffer về cơ bản giống hệt nhau - điểm khác biệt duy nhất là một trong số chúng được thiết kế để sử dụng trong môi trường đa luồng ( StringBuffer ). Các lớp này giống như String nhưng khác ở chỗ chúng có thể thay đổi được . Ngay cả sau khi chúng được tạo, chúng vẫn cho phép bạn sửa đổi các chuỗi mà chúng đại diện mà không cần tạo đối tượng mới. Các phương thức của chúng khác với các phương thức Chuỗi tiêu chuẩn và được thiết kế để thao tác với chuỗi (có lý do khiến họ gọi nó là trình tạo).

58. Có những cách nào để tạo một đối tượng String? Nó được tạo ra ở đâu?

Cách phổ biến nhất để tạo chuỗi là chỉ định giá trị chúng ta muốn trong dấu ngoặc kép một cách đơn giản:
String str = "Hello World!";
Bạn cũng có thể làm điều đó một cách rõ ràng bằng cách sử dụng new :
String str = new String("Hello World!");
Bạn cũng có thể tạo một chuỗi từ một mảng ký tự:
char[] charArr = {'H','e','l','l','o',' ', 'W','o','r','l','d','!'};
String str = new String(charArr);
Chúng ta có thể làm điều đó bằng cách gọi phương thức toString trên một số đối tượng:
String str = someObject.toString();
Chúng ta có thể làm điều đó bằng cách gọi bất kỳ phương thức nào khác trả về một chuỗi. Ví dụ:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String str = reader.readLine();
Bạn hiểu rằng có thể có rất nhiều cách để tạo ra một chuỗi. Khi một đối tượng String được tạo, nó sẽ được lưu trữ trong một nhóm chuỗi , chúng ta sẽ thảo luận chi tiết hơn về một trong các câu hỏi bên dưới.

59. Làm cách nào để so sánh hai chuỗi Java và sắp xếp chúng như thế nào?

Java sử dụng dấu bằng kép ( == ) để thực hiện so sánh. Nếu cần so sánh các giá trị đơn giản như int, chúng ta sẽ sử dụng nó. Nhưng phương pháp này không phù hợp để so sánh các đối tượng chính thức. Nó sẽ chỉ so sánh các tham chiếu, tức là các tham chiếu có trỏ đến cùng một đối tượng hay không. Điều này có nghĩa là nếu chúng ta so sánh hai đối tượng có cùng giá trị trường bằng cách sử dụng == , chúng ta sẽ nhận được sai . Các trường có cùng giá trị nhưng bản thân các đối tượng chiếm các vị trí khác nhau trong bộ nhớ. Các đối tượng chuỗi , mặc dù có vẻ đơn giản đến mức dễ nhầm lẫn, vẫn là các đối tượng. So sánh chúng bằng cách sử dụng == cũng không phù hợp (mặc dù có sự hiện diện của nhóm chuỗi). Giải pháp thích hợp là phương thức bằng tiêu chuẩn của lớp Object , cần được ghi đè để hoạt động chính xác (theo mặc định, nó sử dụng == để so sánh). Lớp String ghi đè lên nó nên chúng ta chỉ sử dụng cách triển khai của nó:
String firstStr = "Hello World!";
String secondStr = "Hello World!";
boolean isEquals = firstStr.equals(secondStr);
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 6 - 6Chúng ta đã nói về sự so sánh để đạt được sự bình đẳng. Bây giờ chúng ta sẽ tìm ra sự so sánh để sắp xếp. Rốt cuộc, nếu chúng ta sắp sắp xếp thứ gì đó, chúng ta cần biết chúng ta sẽ sử dụng nguyên tắc nào để sắp xếp. Để làm điều này, bạn có thể sử dụng TreeSet , một tập hợp được sắp xếp tiêu chuẩn. Cấu trúc dữ liệu này dựa trên thuật toán cây đỏ đen và sắp xếp tập hợp theo nguyên tắc sắp xếp đã chỉ định. Như tôi đã nói trước đó, bạn cần hiểu cách sắp xếp các đối tượng thuộc một loại nhất định. Để chỉ định phương pháp so sánh để sắp xếp, hãy sử dụng bộ so sánh . Bạn thường cần triển khai chúng cho các lớp bạn muốn sắp xếp, nhưng trong trường hợp String , chúng đã được triển khai rồi. Theo đó, chúng ta chỉ cần thêm các chuỗi của mình vào TreeSet nó sẽ sắp xếp chúng cho chúng ta:
TreeSet<String> sortedSet = new TreeSet<>();
sortedSet.add("B");
sortedSet.add("C");
sortedSet.add("A");
sortedSet.forEach(System.out::println);
Đầu ra của bảng điều khiển:
ABC

60. Cung cấp thuật toán chuyển chuỗi thành ký tự. Viết mã tương ứng

Như tôi đã nói trước đó, các đối tượng String có rất nhiều phương thức hữu ích khác nhau. Một trong số đó là toCharArray . Phương thức này chuyển đổi một chuỗi thành một mảng ký tự:
String str = "Hello world";
char[] charArr = str.toCharArray();
Tiếp theo, chúng ta có một mảng các ký tự mà chúng ta có thể tham chiếu theo chỉ mục:
char firstChar = charArr[0]; // H

61. Làm thế nào để chuyển đổi một chuỗi thành một mảng byte và ngược lại? Viết mã tương ứng

Lớp String có phương thức getBytes , tương tự như phương thức toCharArray và trả về chuỗi dưới dạng mảng byte:
String str = "Hello world";
byte[] byteArr = str.getBytes();
byte firstChar = byteArr[6]; // 119
Chúng tôi đã đi đến kết luận hợp lý trong bài đánh giá ngày hôm nay. Cảm ơn vì đã đọc!
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION