Câu hỏi phỏng vấn ngăn xếp cuộc gọi JavaScript

Gần đây tôi đã trả lời một số cuộc phỏng vấn và hầu hết tất cả những người phỏng vấn đều hỏi những câu hỏi tương tự về JavaScript. Vì vậy, tôi muốn chia sẻ kiến ​​thức của mình với tất cả các bạn thông qua blog này

  • JS là đơn luồng hoặc đa luồng
  • JS là đồng bộ hoặc không đồng bộ
  • JS được truyền theo giá trị hoặc được truyền theo tham chiếu
  • Palăng là gì
  • Phạm vi là gì
  • đóng cửa là gì
  • gọi lại là gì
  • Không đồng bộ/Đang chờ

JS là đơn luồng hoặc đa luồng

Javascript là một luồng có nghĩa là nó chỉ có một ngăn xếp cuộc gọi. Ngăn xếp cuộc gọi giống như cấu trúc dữ liệu ngăn xếp và các ngăn xếp là FILO, nhập trước xuất trước. Tương tự, trong ngăn xếp cuộc gọi, bất cứ khi nào một dòng mã vào bên trong ngăn xếp cuộc gọi, nó sẽ được thực thi và di chuyển ra khỏi ngăn xếp. Theo cách này, JavaScript là ngôn ngữ đơn luồng vì chỉ có một ngăn xếp cuộc gọi

JS là đồng bộ hoặc không đồng bộ

Vì JavaScript là một ngôn ngữ đơn luồng nên về bản chất nó là đồng bộ. Như tên cho thấy đồng bộ có nghĩa là trong một trình tự, tôi. e. mọi câu lệnh của mã được thực thi từng cái một.
JavaScript chỉ ở dạng không đồng bộ, chẳng hạn như xử lý hình ảnh hoặc tạo yêu cầu qua mạng như lệnh gọi API.

JS được truyền theo giá trị hoặc được truyền theo tham chiếu

Trong JavaScript, tất cả các đối số của hàm luôn được truyền theo giá trị. Điều đó có nghĩa là JavaScript sao chép các giá trị của các biến truyền vào các đối số bên trong hàm. Bất kỳ thay đổi nào bạn thực hiện đối với các đối số bên trong hàm đều không ảnh hưởng đến các biến truyền bên ngoài hàm.
Nhưng khi bạn truyền một đối tượng và thay đổi các thành phần của nó, những thay đổi đó vẫn tồn tại bên ngoài hàm. Điều này làm cho nó trông giống như được chuyển qua tham chiếu. Nhưng nếu bạn thực sự thay đổi giá trị của biến đối tượng, bạn sẽ thấy rằng sự thay đổi không tồn tại, chứng tỏ nó thực sự được truyền theo giá trị.

Palăng là gì

Hoisting là một cơ chế JavaScript trong đó các khai báo biến và hàm được di chuyển lên đầu phạm vi của chúng trước khi thực thi mã. Điều này có nghĩa là bất kể chức năng và biến được khai báo ở đâu, chúng sẽ được chuyển lên đầu phạm vi của chúng bất kể phạm vi của chúng là toàn cục hay cục bộ.
Nhưng cơ cấu cẩu chỉ di chuyển phần khai báo. Các nhiệm vụ được để lại tại chỗ. Để đọc thêm về nó, hãy nhấp vào đây

Phạm vi là gì

Phạm vi là khả năng truy cập của các biến, hàm và đối tượng trong một số phần cụ thể của mã của bạn trong thời gian chạy. Nói cách khác, phạm vi xác định mức độ hiển thị của các biến và các tài nguyên khác trong các vùng mã của bạn.
Có hai loại phạm vi.
Phạm vi toàn cầu. Một biến nằm trong phạm vi Toàn cầu nếu nó được xác định bên ngoài một hàm.
Phạm vi cục bộ. Các biến được định nghĩa bên trong một hàm nằm trong phạm vi cục bộ.
Để đọc thêm về phạm vi, hãy tham khảo liên kết này

đóng cửa là gì

Một bao đóng là sự kết hợp của một hàm và môi trường từ vựng trong đó hàm đó được khai báo. Nói cách khác, Đóng là một hàm bên trong có quyền truy cập vào các biến của hàm bên ngoài [kèm theo].
Các bao đóng được sử dụng để mở rộng hành vi của các hàm bên ngoài và rất hữu ích khi làm việc với các sự kiện.
Để tìm hiểu sâu về đóng cửa, hãy tham khảo phần này

gọi lại là gì

Gọi lại là một chức năng thực thi sau khi một chức năng khác đã thực thi. Các cuộc gọi lại đảm bảo rằng một chức năng sẽ không chạy trước khi một tác vụ hoàn thành mà sẽ chạy ngay sau khi tác vụ hoàn thành. Tác vụ này có thể là bất kỳ lệnh gọi API nào hoặc bất kỳ tác vụ nào dựa trên bộ hẹn giờ

chắc chắn roll_die[]. trả lại ngẫu nhiên. randint[1, 6] def roll_two_and_sum[]. tổng = 0 tổng += roll_die[] tổng += roll_die[] in tổng roll_two_and_sum[]

Đầu tiên, chương trình của chúng ta gọi rollTwoAndSum . Nó đi vào ngăn xếp cuộc gọi.

rollTwoAndSum

Hàm đó gọi rollDie , hàm này được đẩy lên đầu ngăn xếp cuộc gọi.

rollDie
rollTwoAndSum

Bên trong rollDie , chúng tôi gọi ngẫu nhiên. randint . Đây là ngăn xếp cuộc gọi của chúng tôi trông như thế nào sau đó.

random.randint
rollDie
____0

Khi nào ngẫu nhiên. randint kết thúc, chúng tôi quay lại rollDie bằng cách xóa ["popping"] random.randint .

rollDie
rollTwoAndSum

Điều tương tự khi rollDie trả về.

rollTwoAndSum

Chúng ta chưa hoàn thành. rollTwoAndSum gọi lại rollDie .

rollDie
rollTwoAndSum

Cuộc gọi nào ngẫu nhiên. randint lại.

random.randint
rollDie
____0

ngẫu nhiên. randint trả về, sau đó rollDie trả lại, đưa chúng ta trở lại rollTwoAndSumrollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . rollTwoAndSumrollTwoAndSum . :

rollTwoAndSum

Cuộc gọi nào in .

rollDie
5
rollTwoAndSum

Những gì được lưu trữ trong một khung ngăn xếp?

Điều gì thực sự diễn ra trong khung ngăn xếp của phương thức ?

Một khung ngăn xếp thường lưu trữ

  • Biến cục bộ
  • Các đối số được truyền vào phương thức
  • Thông tin về khung ngăn xếp của người gọi
  • Địa chỉ trả về—chương trình sẽ làm gì sau khi hàm trả về [i. e. nơi nó sẽ "trở lại"]. Đây thường là một nơi nào đó ở giữa mã của người gọi

Một số chi tiết cụ thể khác nhau giữa các kiến ​​trúc bộ xử lý. Chẳng hạn, bộ xử lý AMD64 [64-bit x86] chuyển một số đối số trong thanh ghi và một số trên ngăn xếp cuộc gọi. Và, bộ xử lý ARM [phổ biến trong điện thoại] lưu trữ địa chỉ trả về trong một thanh ghi đặc biệt thay vì đặt nó vào ngăn xếp cuộc gọi

Chi phí không gian của khung ngăn xếp

Mỗi lệnh gọi phương thức tạo khung ngăn xếp riêng, chiếm dung lượng trên ngăn xếp lệnh gọi. Điều đó quan trọng vì nó có thể ảnh hưởng đến độ phức tạp không gian của thuật toán. Đặc biệt là khi chúng ta sử dụng đệ quy.

Ví dụ: nếu chúng tôi muốn nhân tất cả các số giữa 1n, we could use this recursive approach:

public static int product1ToN[int n] { // giả sử n >= 1 return [n > 1] ? . 1;

Ngăn xếp lệnh gọi sẽ như thế nào khi n = 10 ?

Đầu tiên, product1ToN được gọi với n = 10 .

rollDie
7

Đây gọi product1ToN với n = 9 .

rollDie
8
rollDie
7

Gọi product1ToN với n = 8 .

rollTwoAndSum
0____18____17

Và cứ thế cho đến khi chúng ta đạt được n = 1 .

rollTwoAndSum
3
rollTwoAndSum
4
rollTwoAndSum
5
rollTwoAndSum
6
rollTwoAndSum
7
rollTwoAndSum
8
rollTwoAndSum
9
rollTwoAndSum
0
rollDie
8
rollDie
7

Hãy xem kích thước của tất cả các khung ngăn xếp đó. Toàn bộ ngăn xếp cuộc gọi chiếm không gian. Đúng vậy—chúng tôi có chi phí dung lượng mặc dù bản thân phương pháp của chúng tôi không tạo ra bất kỳ cấu trúc dữ liệu nào.

Điều gì sẽ xảy ra nếu chúng ta sử dụng phương pháp lặp thay vì phương pháp đệ quy?

public static int product1ToN[int n] { // giả sử n >= 1 int result = 1;

Phiên bản này chiếm dung lượng không đổi. Khi bắt đầu vòng lặp, ngăn xếp cuộc gọi trông như thế này

random.randint
3

Khi chúng tôi lặp qua vòng lặp, các biến cục bộ thay đổi, nhưng chúng tôi vẫn ở trong cùng một khung ngăn xếp vì chúng tôi không gọi bất kỳ hàm nào khác

random.randint
4
random.randint
5
random.randint
6

Nói chung, mặc dù trình biên dịch hoặc trình thông dịch sẽ đảm nhận việc quản lý ngăn xếp cuộc gọi cho bạn, nhưng điều quan trọng là phải xem xét độ sâu của ngăn xếp cuộc gọi khi phân tích độ phức tạp về không gian của thuật toán

Đặc biệt cẩn thận với các hàm đệ quy. Cuối cùng, họ có thể xây dựng ngăn xếp cuộc gọi khổng lồ

Điều gì xảy ra nếu chúng tôi hết dung lượng? . Trong Java , bạn sẽ gặp Lỗi StackOverflow.

Nếu điều cuối cùng mà một phương thức thực hiện là gọi một phương thức, then its stack frame might not be needed any more. The phương thức có thể giải phóng khung ngăn xếp của nó trước khi thực hiện lệnh gọi cuối cùng, giúp tiết kiệm dung lượng.

Điều này được gọi là tối ưu hóa cuộc gọi đuôi [TCO]. Nếu một hàm đệ quy được tối ưu hóa với TCO, thì nó có thể không kết thúc bằng một ngăn xếp cuộc gọi lớn

Nói chung, hầu hết các ngôn ngữ không cung cấp TCO. Scheme là một trong số ít ngôn ngữ đảm bảo tối ưu hóa cuộc gọi đuôi. Một số triển khai Ruby, C và Javascript có thể làm điều đó. Python và Java quyết định không

Chia sẻ Tweet Chia sẻ

Phỏng vấn sắp tới?

Nhận khóa học xử lý email miễn phí trong 7 ngày. Bạn sẽ học cách suy nghĩ theo thuật toán, vì vậy bạn có thể phá vỡ các câu hỏi phỏng vấn viết mã phức tạp

Không cần đào tạo về khoa học máy tính trước—chúng tôi sẽ giúp bạn bắt kịp tốc độ một cách nhanh chóng, bỏ qua tất cả những nội dung quá hàn lâm

Câu hỏi phỏng vấn xếp hàng đợi là gì?

25 câu hỏi phỏng vấn xếp chồng hàng đầu .
Q1. .
quý 2. .
Tại sao và khi nào tôi nên sử dụng cấu trúc dữ liệu Ngăn xếp hoặc Hàng đợi thay vì Mảng/Danh sách?.
Tại sao ngăn xếp hữu ích?.
Làm cách nào để triển khai Danh sách được liên kết bằng Stack?.
So sánh việc triển khai ngăn xếp dựa trên mảng và danh sách được liên kết. .
Giải thích Biểu thức Infix, Prefix và Postfix là gì?

Những câu hỏi nào được hỏi trong cuộc phỏng vấn JavaScript?

Câu hỏi và câu trả lời phỏng vấn JavaScript dành cho người mới bắt đầu .
Q1. Sự khác biệt giữa Java & JavaScript là gì?
quý 2. JavaScript là gì?
Q3. Các loại dữ liệu được hỗ trợ bởi JavaScript là gì?
Q4. Các tính năng của JavaScript là gì?
Q5. JavaScript có phải là ngôn ngữ phân biệt chữ hoa chữ thường không?
Q6. .
Q7. .

Gọi lại trong câu hỏi phỏng vấn JavaScript là gì?

Một hàm gọi lại JavaScript là một hàm sẽ được thực thi sau khi một hàm khác đã thực thi xong . Một định nghĩa chính thức hơn sẽ là - Bất kỳ hàm nào được truyền dưới dạng đối số cho hàm khác để nó có thể được thực thi trong hàm khác đó được gọi là hàm gọi lại.

Tôi có thể bẻ khóa cuộc phỏng vấn của Google bằng JavaScript không?

Tôi có thể sử dụng JavaScript để phỏng vấn không? . Tuy nhiên, lưu ý rằng nếu người phỏng vấn muốn kiểm tra kỹ năng của bạn bằng một ngôn ngữ cụ thể, thì điều đó sẽ thay đổi. Nếu giải pháp tốt hơn nhiều trong một ngôn ngữ OOP khác, bạn nên có lý do chính đáng để không chọn nó. Yes, as long as that's the language you know best, you can usually use it. Note, however, that if interviewers want to check your skill in a particular language, that changes. If the solution is much better in a different OOP language, you should have a good reason not to choose it.

Chủ Đề