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 1

Xuất bản trong nhóm
Xin chào! Nhiều người đã tập trung tại JavaRush. Một số người trong chúng ta chỉ muốn trở thành nhà phát triển Java, đầu tư nhiều thời gian và công sức vào việc phát triển, trong khi những người khác đã là nhà phát triển Java. Trong trường hợp này hay trường hợp khác, bạn cần chuẩn bị cho các bài kiểm tra - phỏng vấn kỹ thuật. Bài kiểm tra này không hề dễ dàng, ngoài việc chuẩn bị về mặt đạo đức thì cũng cần chuẩn bị về mặt kỹ thuật. Phân tích câu hỏi và câu trả lời phỏng vấn.  Phần 1 - 1Gần đây tôi đã xem được một danh sách lớn các Câu hỏi phỏng vấn nhà phát triển Java trên dou. Những câu hỏi này được chia thành các cấp độ khác nhau - Junior, Middle và Senior. Đừng lo lắng: không phải tất cả các câu hỏi đều dễ dàng, nhưng những câu hỏi có dấu hoa thị hiếm khi được hỏi. Các câu hỏi rất hay, nhưng tôi muốn cố gắng trả lời hầu hết chúng. Rõ ràng là tôi sẽ không đi sâu vào phạm vi của một bài viết, xét cho cùng thì có rất nhiều câu hỏi ở đó. Vì vậy, đây sẽ là cả một loạt bài viết giải đáp những câu hỏi như vậy. Hãy để tôi nhấn mạnh ngay một vài điểm:
  1. Có một bài viết xuất sắc với những câu hỏi và câu trả lời hàng đầu dành cho họ. Một số câu hỏi trùng lặp với danh sách được trình bày ở trên (250+), vì vậy những câu hỏi này sẽ được bỏ qua để không trùng lặp thông tin một lần nữa.

  2. Các câu hỏi được trình bày bằng tiếng Ukraina, nhưng vì phần lớn người tham gia JavaRush là người nói tiếng Nga (và ở mức độ lớn hơn là tôi cũng vậy), nên câu trả lời sẽ bằng tiếng Nga.

  3. Các câu trả lời sẽ ngắn gọn, vì nếu bạn viết rất chi tiết, câu trả lời cho một số câu hỏi có thể cần một bài viết riêng. Và trong các cuộc phỏng vấn, những câu trả lời chi tiết và đồ sộ như vậy là không cần thiết, bởi vì người phỏng vấn bạn chỉ có một giờ để phỏng vấn bạn về những chủ đề cần thiết (và, như bạn nhớ, thế là đủ). Đối với những người thích tìm hiểu sâu hơn, tôi sẽ để lại liên kết.

Vì vậy, hãy bắt đầu.

Câu hỏi và câu trả lời cấp cơ sở

Phân tích câu hỏi và câu trả lời phỏng vấn.  Phần 1 - 2

Các vấn đề chung

1. Bạn biết những mẫu thiết kế nào? Hãy cho chúng tôi biết về hai mẫu bạn đã sử dụng trong công việc của mình.

Có rất nhiều mẫu: bạn có thể bắt đầu làm quen với chúng từ bài viết này và bài viết này. Chà, đối với những ai muốn tìm hiểu chi tiết về chúng, tôi khuyên bạn nên đọc cuốn sách “Head First. Mẫu thiết kế" . Với sự trợ giúp của nó, bạn có thể nghiên cứu các mẫu thiết kế cơ bản nhất một cách chi tiết và dễ dàng. Khi nói đến các mẫu thiết kế mà bạn có thể sử dụng làm ví dụ trong một cuộc phỏng vấn, một số mẫu bạn có thể nghĩ đến là:
  • Builder là một mẫu được sử dụng thường xuyên, một giải pháp thay thế cho việc tạo đối tượng cổ điển;
  • Mẫu chiến lược vốn dĩ đại diện cho tính đa hình. Nghĩa là, chúng ta có một giao diện, nhưng hành vi của chương trình sẽ thay đổi tùy thuộc vào cách triển khai cụ thể của giao diện này được chuyển sang chức năng (hiện tại, chiến lược này thực tế được sử dụng ở mọi nơi trong các ứng dụng java).
Nếu điều này vẫn chưa đủ đối với bạn, hãy chú ý đến Spring (nếu bạn đã quen thuộc với nó), bởi vì nó là toàn bộ nền tảng của các framework, do đó có rất nhiều mẫu hình lên xuống. Dưới đây là một vài ví dụ về những gì tôi đang nói đến:
  • Nhà máy - trong ApplicationContext (hoặc trong BeanFactory);
  • Singleton - theo mặc định, tất cả các loại đậu đều là singleton;
  • Proxy - về cơ bản mọi thứ trong mùa xuân đều sử dụng mẫu này theo cách này hay cách khác, chẳng hạn như AOP;
  • Chuỗi trách nhiệm là một mô hình dựa trên khái niệm mà Spring Security hoạt động;
  • Mẫu - được sử dụng trong Spring Jdbc.

Lõi Java

Phân tích câu hỏi và câu trả lời phỏng vấn.  Phần 1 - 3

2. Có những kiểu dữ liệu nào trong Java?

Java có các kiểu dữ liệu nguyên thủy:
  • byte - số nguyên trong phạm vi -128 đến 127, nặng 1 byte;
  • ngắn - số nguyên trong phạm vi -32768 đến 32767, nặng 2 byte;
  • int - số nguyên -2147483648 đến 2147483647, nặng 4 byte;
  • dài - số nguyên trong phạm vi 9223372036854775808 đến 9223372036854775807, nặng 8 byte;
  • float - số dấu phẩy động trong phạm vi -3,4E+38 đến 3,4E+38, nặng 4 byte;
  • double — số dấu phẩy động trong phạm vi -1,7E+308 đến 1,7E+308, nặng 8 byte;
  • char - ký tự đơn trong UTF-16, nặng 2 byte;
  • giá trị boolean đúng/sai , nặng 1 byte.
các kiểu dữ liệu tham chiếu , trỏ đến các đối tượng trên vùng nhớ heap.

3. Đối tượng khác với kiểu dữ liệu nguyên thủy như thế nào?

Sự khác biệt đầu tiên: lượng bộ nhớ bị chiếm dụng: các đối tượng nguyên thủy chiếm rất ít, vì chúng chỉ chứa giá trị của chính chúng, trong khi các đối tượng có thể chứa rất, rất nhiều giá trị khác nhau: cả nguyên thủy và tham chiếu đến các đối tượng khác. Điểm khác biệt thứ hai: Java là ngôn ngữ hướng đối tượng, vì vậy mọi thứ trong nó hoạt động thông qua sự tương tác giữa các đối tượng và các ngôn ngữ nguyên thủy không phù hợp lắm (trên thực tế, đây là lý do tại sao Java không phải là ngôn ngữ hướng đối tượng 100%). Thứ ba, tiếp theo từ thứ hai: vì Java tập trung vào sự tương tác giữa các đối tượng nên các đối tượng này có nhiều cơ chế khác nhau để quản lý chúng. Ví dụ: hàm tạo, phương thức, ngoại lệ (hoạt động chủ yếu trên các đối tượng), v.v. Trên thực tế, để các kiểu nguyên thủy bằng cách nào đó có thể tham gia (làm việc) vào môi trường hướng đối tượng này, các trình bao bọc đã được phát minh cho các kiểu nguyên thủy ( Integer , Character , Double , Boolean ...)

4. Sự khác biệt giữa việc truyền tham số theo tham chiếu và theo giá trị là gì?

Các trường nguyên thủy lưu trữ giá trị của chúng: ví dụ: nếu chúng ta đặt int i = 9; trường tôi lưu trữ giá trị 9 . Khi chúng ta có một tham chiếu đến một đối tượng, điều này có nghĩa là chúng ta có một trường có tham chiếu đến đối tượng đó, hay nói cách khác là có giá trị địa chỉ của đối tượng trong bộ nhớ.
Cat cat = new Cat();
Hóa ra các trường có tham chiếu đến một đối tượng cũng lưu trữ các giá trị , giá trị địa chỉ bộ nhớ. Nghĩa là, cat lưu trữ giá trị địa chỉ của đối tượng Cat() mới trong bộ nhớ. Khi chúng ta truyền một tham số cho một phương thức, giá trị của nó sẽ được sao chép. Trong trường hợp nguyên thủy, giá trị của nguyên thủy sẽ được sao chép. Theo đó, phương pháp sẽ hoạt động với bản sao, việc thay đổi sẽ không ảnh hưởng đến bản gốc. Trong trường hợp là kiểu tham chiếu, giá trị của địa chỉ bộ nhớ sẽ được sao chép tương ứng, địa chỉ sẽ giống với đối tượng mà nó trỏ tới. Và nếu chúng ta thay đổi đối tượng bằng liên kết mới này, nó sẽ được thay đổi đối với đối tượng cũ (dù sao thì cả hai đều trỏ đến cùng một đối tượng).

5. JVM, JDK, JRE là gì?

JVM - Máy ảo Java là một máy ảo chạy mã byte Java được trình biên dịch tạo trước. JRE - Môi trường chạy thi hành Java - về cơ bản là môi trường để chạy các ứng dụng java, chứa JVM , các thư viện chuẩn và các thành phần khác để chạy các applet và ứng dụng được viết bằng ngôn ngữ lập trình Java. Nói cách khác , JRE là gói chứa mọi thứ cần thiết để chạy một chương trình Java đã biên dịch, nhưng không chứa các công cụ và tiện ích như trình biên dịch hoặc trình gỡ lỗi để phát triển ứng dụng. JDK - Bộ công cụ phát triển Java - một bộ JRE mở rộng , tức là một môi trường không chỉ để khởi chạy mà còn để phát triển các ứng dụng Java. JDK chứa mọi thứ có trong JRE, cùng với nhiều công cụ bổ sung khác - trình biên dịch và trình gỡ lỗi cần thiết để tạo ứng dụng trong Java (cũng chứa các tài liệu java).Phân tích câu hỏi và câu trả lời phỏng vấn.  Phần 1 - 4

6. Tại sao nên sử dụng JVM?

Như đã đề cập ở trên, Máy ảo Java là một máy ảo chạy mã byte Java được trình biên dịch tạo trước. Tức là JVM không hiểu mã nguồn Java. Do đó, trước tiên, các tệp .java được biên dịch , sau khi biên dịch đã có phần mở rộng .class và được trình bày dưới dạng cùng một mã byte mà JVM hiểu được. Mỗi hệ điều hành có JVM riêng, do đó, sau khi nhận được các tệp mã byte, JVM sẽ thực thi nó, điều chỉnh nó cho phù hợp với hệ điều hành nơi nó xảy ra. Trên thực tế, do các JVM khác nhau, các phiên bản JDK (hoặc JRE) khác nhau đối với các hệ điều hành khác nhau (mỗi hệ điều hành yêu cầu JVM riêng). Hãy nhớ cách phát triển hoạt động trong các ngôn ngữ lập trình khác. Bạn phát triển một chương trình, sau đó mã của nó được biên dịch thành mã máy cho một hệ điều hành cụ thể và sau đó bạn có thể chạy chương trình đó. Nói cách khác, bạn cần viết các phiên bản khác nhau của chương trình cho mỗi hệ thống. Trong khi đó ở Java, nhờ xử lý mã kép (biên dịch và xử lý byte mã JVM), bạn có thể tận hưởng những lợi ích của đa nền tảng. Chúng tôi đã từng tạo mã, biên dịch lại thành mã byte, chuyển nó sang bất kỳ hệ điều hành nào và JVM cục bộ sẽ chạy mã. Đây là đặc tính huyền thoại của Java - viết một lần, chạy mọi nơi . Phân tích câu hỏi và câu trả lời phỏng vấn.  Phần 1 - 5Đọc thêm về điều này trong bài viết “ Biên dịch và thực thi các ứng dụng Java cơ bản ”.

7. Mã byte là gì?

Như tôi đã nói ở trên, trình biên dịch chuyển đổi mã Java thành mã byte trung gian (các tệp có phần mở rộng .java thành các tệp có phần mở rộng .class). Bytecode về nhiều mặt tương tự như mã máy, chỉ khác là nó sử dụng một bộ hướng dẫn không phải từ bộ xử lý thực mà từ bộ xử lý ảo. Hơn nữa, nó có thể bao gồm các phần tập trung vào việc sử dụng trình biên dịch JIT, giúp tối ưu hóa việc thực thi các lệnh cho bộ xử lý thực mà chương trình đang chạy trên đó. Biên dịch JIT, còn được gọi là biên dịch nhanh chóng, là một công nghệ giúp tăng hiệu suất của chương trình sử dụng mã byte bằng cách biên dịch mã byte thành máy hoặc định dạng khác trong khi chương trình đang chạy. Như bạn có thể đoán, JVM sử dụng trình biên dịch JIT khi chạy mã byte. Chúng ta hãy xem một ví dụ về mã byte: Phân tích câu hỏi và câu trả lời phỏng vấn.  Phần 1 - 6Không dễ đọc lắm phải không? Chà, đây không phải là hướng dẫn dành cho chúng tôi mà dành cho JVM. Dưới đây là bài viết sẽ giúp bạn hiểu rõ hơn về vấn đề này.

8. Đặc điểm của JavaBean là gì?

JavaBeans là một lớp Java có các quy tắc nhất định. Dưới đây là một số quy tắc để viết JavaBean :
  1. Lớp này phải chứa một hàm tạo truy cập công khai trống (không có tham số) cùng với bộ sửa đổi truy cập công khai . Hàm tạo này cho phép tạo một đối tượng của lớp này mà không gặp vấn đề không cần thiết (để không có sự phiền phức không cần thiết với các tham số).

  2. Các trường nội bộ của một lớp được truy cập thông qua các phương thức getset , đây phải là tiêu chuẩn. Ví dụ: nếu trường là name thì getNamesetName, v.v. Điều này cho phép các công cụ (khung) khác nhau tự động xác định và cập nhật nội dung của đậu mà không gặp rắc rối.

  3. Lớp này phải chứa các phiên bản được ghi đè của các phương thức bằng() hashCode()toString() .

  4. Lớp phải có khả năng tuần tự hóa, tức là nó phải có giao diện đánh dấu - Serializable hoặc triển khai giao diện Bên ngoài . Điều này là cần thiết để trạng thái của đậu có thể được lưu, lưu trữ và khôi phục một cách đáng tin cậy.

Phân tích câu hỏi và câu trả lời phỏng vấn.  Phần 1 - 7Bạn có thể đọc về các loại JavaBeans trong tài liệu này .

9. OutOfMemoryError là gì?

OutOfMemoryError là một trong những lỗi thời gian chạy nghiêm trọng liên quan đến hoạt động của Máy ảo Java (JVM). Được gọi khi JVM không thể phân bổ một đối tượng vì không có đủ bộ nhớ cho nó và trình thu gom rác không thể phân bổ thêm bộ nhớ. Một số loại OutOfMemoryError :
  • OutOfMemoryError: Không gian vùng heap Java - đối tượng không thể được phân bổ trên vùng heap Java do không đủ bộ nhớ. Lỗi có thể do rò rỉ bộ nhớ hoặc do kích thước heap mặc định không đủ lớn cho ứng dụng hiện tại.

  • OutOfMemoryError: Đã vượt quá giới hạn chi phí của GC - do lượng dữ liệu hầu như không vừa trong heap, trình thu thập rác luôn chạy và chương trình Java chạy rất chậm và kết quả là giới hạn chi phí của trình thu gom rác vượt quá và ứng dụng gặp sự cố với lỗi này.

  • OutOfMemoryError: Kích thước mảng được yêu cầu vượt quá giới hạn VM - cho biết ứng dụng đã cố phân bổ bộ nhớ cho một mảng lớn hơn kích thước vùng heap, điều này một lần nữa có thể là do phân bổ bộ nhớ mặc định không đủ.

  • OutOfMemoryError: Metaspace — vùng heap đã hết dung lượng được phân bổ cho siêu dữ liệu (siêu dữ liệu là hướng dẫn cho các lớp và phương thức).

  • OutOfMemoryError: yêu cầu kích thước byte vì lý do. Hết dung lượng trao đổi - đã xảy ra một số lỗi khi cố gắng phân bổ bộ nhớ từ vùng heap và kết quả là thiếu bộ nhớ trong vùng heap.

10. Dấu vết ngăn xếp là gì? Làm thế nào để có được nó?

Dấu vết ngăn xếp là danh sách các lớp và phương thức đã được gọi cho đến thời điểm này trong ứng dụng. Bạn có thể gọi dấu vết ngăn xếp tại một điểm cụ thể trong ứng dụng như sau:
StackTraceElement[] stackTraceElements =Thread.currentThread().getStackTrace();
Bằng cách này chúng ta sẽ có được một mảng các phần tử dấu vết ngăn xếp được sắp xếp theo thứ tự LIFO - Last In First Out . Phân tích câu hỏi và câu trả lời phỏng vấn.  Phần 1 - 8Trong Java, theo quy luật, khi họ nói về dấu vết ngăn xếp, họ có nghĩa là dấu vết ngăn xếp được hiển thị trong bảng điều khiển khi xảy ra lỗi (hoặc ngoại lệ). Bạn có thể lấy dấu vết ngăn xếp của các trường hợp ngoại lệ như thế này:
StackTraceElement[] stackTraceElements;
try{
                ...
} catch (Exception e) {
   stackTraceElements = e.getStackTrace();
}
Chà, nếu chúng ta đang nói về việc xuất dấu vết ngăn xếp ngoại lệ trong bảng điều khiển:
try{
                ...
} catch (Exception e) {
  e.printStackTrace();
}
Ngoài ra, nếu chúng tôi gặp lỗi, một ngoại lệ không được kiểm tra hoặc một ngoại lệ đã kiểm tra , chúng tôi sẽ không xử lý mà chỉ chuyển tiếp, thì khi ứng dụng gặp sự cố, chúng tôi sẽ tự động nhận được dấu vết ngăn xếp các ngoại lệ trong bảng điều khiển. Một ví dụ nhỏ về ngoại lệ theo dõi ngăn xếp trong bảng điều khiển: Phân tích câu hỏi và câu trả lời phỏng vấn.  Phần 1 - 9Bạn có thể đọc thêm về Dấu vết ngăn xếp tại đây . Chúng ta sẽ tập trung vào vấn đề này ngày hôm nay...Phân tích câu hỏi và câu trả lời phỏng vấn.  Phần 1 - 10
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