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 Show
JS là đơn luồng hoặc đa luồngJavascript 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. JS được truyền theo giá trị hoặc được truyền theo tham chiếuTrong 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. 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ộ. 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. đó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). 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 ____0Khi 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 ____0ngẫ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 5rollTwoAndSum 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ữ
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ếpMỗ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 1 và n, 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 8rollDie 7Gọi product1ToN với n = 8 . rollTwoAndSum 0____18____17Và cứ thế cho đến khi chúng ta đạt được n = 1 . rollTwoAndSum 3rollTwoAndSum 4rollTwoAndSum 5rollTwoAndSum 6rollTwoAndSum 7rollTwoAndSum 8rollTwoAndSum 9rollTwoAndSum 0rollDie 8rollDie 7Hã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 3Khi 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 4random.randint 5random.randint 6Nó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. |