JavaRush /Blog Java /Random-VI /Phân tích các câu hỏi và câu trả lời từ các cuộc phỏng vấ...

Phân tích các câu hỏi và câu trả lời từ các cuộc phỏng vấn dành cho nhà phát triển Java. Phần 6

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

Tôi nghĩ để trả lời câu hỏi này, trước tiên chúng ta cần hiểu JPA là gì . JPA 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 đó. Đó là, như chúng ta nhớ, cơ sở dữ liệu quan hệ (DB) được trình bày dưới dạng nhiều bảng được kết nối với nhau. Và JPA là một tiêu chuẩn được chấp nhận 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. Phân tích các câu hỏi và câu trả lời từ các cuộc phỏng vấn dành cho nhà phát triển Java.  Phần 6 - 3Đồng thời, Hibernate là một thư viện cụ thể triển khai các mô hình JPA . Nghĩa là, với sự trợ giúp của thư viện này, bạn có thể làm việc với cơ sở dữ liệu quan hệ thông qua các đối tượng biểu thị dữ liệu từ cơ sở dữ liệu (Thực thể). Như họ nói, thư viện này rất gần với lý tưởng của JPA và có lẽ đó là lý do tại sao nó trở nên phổ biến. Và như bạn hiểu, mức độ phổ biến của việc sử dụng là một lý lẽ thuyết phục cho sự phát triển và cải tiến hơn nữa. Ngoài ra, đằng sau việc sử dụng thường xuyên nó còn có một cộng đồng khổng lồ đã giải quyết tất cả các câu hỏi có thể và không thể liên quan đến công cụ này. Đây là một ví dụ về một cuốn sách xem xét chi tiết tất cả những góc tối của công nghệ này. Nghĩa là, Hibernate đã được nghiên cứu nhiều nhất có thể và hóa ra là đáng tin cậy. Trên thực tế, không phải vô cớ mà ngay cả việc triển khai JPA lý tưởng ở phía Spring cũng thường sử dụng Hibernate dưới mui xe.

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 được thực hiện 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 một số bảng cụ thể trong cơ sở dữ liệu và như bạn nhớ, trong 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 phản ánh trong cơ sở dữ liệu. Trong cơ sở dữ liệu, theo quy tắc, đây là các khóa ngoại (đối với OneToOne, OneToMany, ManyToOne) hoặc các bảng trung gian (đối với ManyToMany). Bạn có thể đọc thêm về mối quan hệ giữa các thực thể trong bài viết này . Khi thực thể của bạn có liên kết đến các thực thể liên quan khác, các chú thích sẽ được đặt phía trên các liên kết này để cho biết loại kết nối: @OneToOne, @OneToMany, @ManyToOne, @ManyToMane, trong các tham số của chúng, bạn có thể chỉ định giá trị của thuộc tính - Cascade - the loại tầng cho kết nối này. 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 chính xác để hiển thị cách dữ liệu liên quan sẽ hoạt động khi các phương thức này được sử dụng trên thực thể đích. Vì vậy, các chiến lược xếp tầng (các loại xếp tầng) là gì? Tiêu chuẩn JPA ngụ ý việc sử dụng sáu loại xếp tầng:
  • KIÊN TRÌ - các hoạt động lưu sẽ diễn ra theo tầng (đối với các phương thức save()Persist() ). Nghĩa là, 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ì chúng 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 sẽ diễn ra theo tầng (đối với phương thức merge() )

  • XÓA - các hoạt động loại bỏ xảy ra theo tầng ( phương thức Remove() )

  • TẤT CẢ - chứa ba hoạt động xếp tầng cùng một lúc - KIÊN TRÌ - MERGE - LOẠI BỎ

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

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

Phân tích các câu hỏi và câu trả lời từ các cuộc phỏng vấn dành cho 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 nhưng cũng giới thiệu ba hoạt động riêng:
  • REPLICATE - Được sử dụng khi chúng ta có nhiều nguồn dữ liệu và muốn dữ liệu được đồng bộ hóa (Phương thức Hibernate - sao chép). Tất cả các thực thể phải có số nhận dạng (id) để không gặp vấn đề gì khi tạo chúng (để cùng một thực thể không có các id khác nhau cho các cơ sở dữ liệu khác nhau)

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

  • LOCK là hoạt động ngược lại với DETACHED : nó chuyển thực thể tách rời trở lại trạng thái tồn tại , tức là. thực thể sẽ được theo dõi lại bởi phiên hiện tại

Nếu loại xếp tầng không được chọn thì không có thao tác nào trên một thực thể sẽ có bất kỳ ảnh hưởng nào đế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?

Trong đặc tả JPA , ở đoạn 2.1 The Entity Class có một dòng: “ Cả hai lớp trừu tượng và cụ thể đều có thể là các 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 chú thích bằng @Entity.

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

Trước hết, tôi muốn lưu ý rằng EntityManager là một trong những thành phần chính của JPA , được sử dụng để tương tác các thực thể với cơ sở dữ liệu. Nói chung, nó gọi các phương thức tương tác giữa thực thể và cơ sở dữ liệu (lưu giữ, hợp nhất, xóa, tách)... Nhưng tôi cũng lưu ý rằng thành phần này, theo quy tắc, không phải là một thành phần cho toàn bộ ứng dụng: thường xuyên nhất nó nhẹ và thường 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 vẽ song song với JDBC , trong đó EntityManagerFactory sẽ tương tự như DataSource , thì đến lượt EntityManager sẽ là tương tự của Connection . Trước đó tôi đã đề cập đến một thực thể bền vững , là một thực thể được kiểm soát bởi kết nối hiện tại. Vì vậy: thực thể này được quản lý chính xác 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. Hơn nữa trong hình bên dưới, bạn có thể thấy vòng đời của một thực thể: Разбор вопросов и ответов с собеседований на Java-разработчика. Часть 6 - 5EntityManager quản lý thực thể khi nó ở giai đoạn Được quản lý (tại thời điểm này nó liên tục vì nó có kết nối với EntityManager). Tức là nó không còn mới và chưa bị loại bỏ. Chúng ta có thể nói rằng khi một thực thể là mới hoặc bị loại bỏ, nó cũng bị tách rời, bởi vì nó không được quản lý bởi EntityManager. Có nhiều chiến lược khác nhau cho EntityManager. Nghĩa là, có thể có một EntityManager đơn lẻ cho toàn bộ ứng dụng hoặc có thể tạo một cái mới mỗi lần, cho mỗi kết nối. Nếu bạn sử dụng Spring, thì việc tạo/xóa EntityManager sẽ được điều khiển tự động một cách tự động (nhưng điều này không có nghĩa là bạn không thể tùy chỉnh nó ^^). Điều đáng nói là một hoặc nhiều EntityManager tạo thành bối cảnh bền vững . Bối cảnh liên tục là một 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 những khái niệm này.

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

Tôi chưa nghe nói về một lớp như vậy trong JPA , vì vậy tôi sẽ cho rằng điều này đề cập đến lớp JUnit của thư viện, được sử dụng để kiểm tra đơn vị mã. Lớp của thư viện này, Assert , được sử dụng để kiểm tra kết quả thực thi mã ( khẳng định là một tuyên bố rằng bạn có một trạng thái/dữ liệu nhất định ở một nơi nhất định). Ví dụ: bạn đang thử nghiệm một phương pháp tạo ra một con mèo. Bạn chạy một phương thức và 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? Do đó, trước đây bạn đã tạo một con mèo nhất định - ExpectCat - theo cách thủ công với chính xác các tham số mà bạn mong đợi từ con mèo thu được từ phương thức createCat() . Tiếp theo, 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, một ngoại lệ AssertionError sẽ được ném ra , điều này cho chúng ta biết rằng kết quả mong đợi không hội tụ. Lớp Assert có nhiều phương thức khác nhau bao gồm nhiều nhiệm vụ xác minh kết quả mong đợi. Dưới đây là một số trong số họ:
  • khẳng địnhTrue(<boolean>) - giá trị mong đợi nhận được dưới dạng đối số phải đúng

  • khẳng địnhFalse(<boolean>) - giá trị mong đợi nhận được dưới dạng đối số phải sai

  • khẳng địnhNotEquals(<object1>, <object2>) - các đối tượng nhận được 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 được dự kiến ​​là một ngoại lệ của lớp được chỉ định bởi đối số thứ nhất (tức là, theo quy tắc, thay cho đối số thứ hai, một phương thức được gọi sẽ ném một ngoại lệ của loại được yêu cầu)

Sợi dây

57. Ký tự chuỗi trong Java

String là một lớp tiêu chuẩn trong Java, chịu trách nhiệm lưu trữ và thao tác các giá trị chuỗi (chuỗi ký tự), là một lớp bất biến ( tôi đã viết về bất biến trước đó ), tức là. Dữ liệu của các đối tượng thuộc lớp này không thể thay đổi sau khi tạo. Tôi muốn lưu ý ngay rằng các lớp StringBuilderStringBuffer là hai lớp gần như giống hệt nhau với đ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 tương tự như String nhưng không giống như String, chúng có thể thay đổi được . Nghĩa là, các đối tượng sau khi được tạo sẽ cho phép sửa đổi chuỗi mà chúng biểu thị mà không cần tạo đối tượng mới. Trên thực tế, các phương thức này khác với các phương thức Chuỗi tiêu chuẩn và nhằm mục đích đáp ứng nhu cầu thay đổi chuỗi (không phải vô cớ mà chúng được gọi là trình tạo). Đọc thêm về String , StringBufferStringBuilder trong bài viết này .

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ỉ cần chỉ định giá trị chúng ta cần trong dấu ngoặc kép:
String str = "Hello World!";
Bạn cũng có thể thực hiện việc này trực tiếp thông qua new :
String str = new String("Hello World!");
Bạn có thể tạo một chuỗi bắt đầu từ một mảng ký tự:
char[] charArr = {'H','e','l','l','o',' ', 'W','o','r','l','d','!'};
String str = new String(charArr);
Là kết quả của phương thức toString chạy trên một số đối tượng:
String str = someObject.toString();
Giống như kết quả của bất kỳ phương thức nào khác, nó trả về một biểu diễn chuỗi. Ví dụ:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String str =  reader.readLine();
Như bạn đã hiểu, có thể có rất, rất nhiều cách để tạo một chuỗi. Khi một đối tượng String được tạo, nó sẽ được lưu trữ trong nhóm chuỗi , chúng ta sẽ nói chi tiết hơn về điều này trong một trong các câu hỏi bên dưới.

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

Để so sánh các giá trị trong Java, dấu bằng kép == được sử dụng . Nếu cần so sánh một số 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 thể áp dụng để so sánh các đối tượng chính thức. Trong trường hợp này, nó sẽ chỉ là so sánh các tham chiếu - cho dù chúng có trỏ đến cùng một đối tượng hay không. Nghĩa là khi so sánh hai đối tượng có cùng giá trị các trường bên trong, so sánh thông qua == sẽ cho kết quả sai : mặc dù các trường của đối tượng giống hệt nhau nhưng bản thân các đối tượng lại chiếm các ô nhớ khác nhau. Và các đối tượng của lớp String , mặc dù có vẻ đơn giản đến mức dễ nhầm lẫn, nhưng vẫn là các đối tượng. Và so sánh qua == cũng không thể áp dụng cho chúng (ngay cả khi có sự hiện diện của nhóm chuỗi). Ở đây, phương thức tiêu chuẩn của lớp Object phát huy tác dụng - Equals , phương thức này phải được ghi đè trong lớp để nó hoạt động chính xác (nếu không, theo mặc định, nó sẽ so sánh bằng cách sử dụng == ). Nó bị ghi đè trong lớp String nên chúng ta chỉ cần lấy và sử dụng:
String firstStr = "Hello World!";
String secondStr = "Hello World!";
boolean isEquals = firstStr.equals(secondStr);
Разбор вопросов и ответов с собеседований на Java-разработчика. Часть 6 - 6Chúng ta đã nói về so sánh phù hợp, bây giờ hãy xem xét so sánh sắp xếp. Suy cho cùng, để sắp xếp một thứ gì đó chúng ta cần biết cần sắp xếp theo nguyên tắc nào. Để thực hiện việc này, bạn có thể sử dụng bộ được sắp xếp tiêu chuẩn - TreeSet . Bạn có thể đọc thêm về các bộ sưu tập khác nhau trong Java trong bài viết này . Danh sách này hoạt động 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. Bộ so sánh được sử dụng để thiết lập phương pháp so sánh để sắp xếp . Thông thường, những điều này cần được triển khai cho các lớp bạn muốn sắp xếp, nhưng trong trường hợp Chuỗi thì chúng đã được triển khai rồi. Do đó, chúng ta chỉ cần thêm các hàng chúng ta cần vào TreeSet và nó sẽ sắp xếp chúng:
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:
A B C

60. Đưa ra thuật toán chuyển một chuỗi thành một ký tự. Viết mã thích hợp

Như tôi đã nói trước đó, các đối tượng của lớp 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ể gọi 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ảng byte và ngược lại? Viết mã thích hợp

Tương tự như phương thức toCharArray , lớp String có phương thức getBytes trả về một mảng byte của chuỗi:
String str = "Hello world";
byte[] byteArr = str.getBytes();
byte firstChar = byteArr[6]; // 119
Phần phân tích hôm nay đã đi đến hồi kết hợp lý. Cám ơn vì sự quan tâm của bạn!Разбор вопросов и ответов с собеседований на Java-разработчика. Часть 6 - 7
Các tài liệu khác trong loạt bài:
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION