后端开发面试题10(附答案)

发布于:2024-11-02 ⋅ 阅读:(69) ⋅ 点赞:(0)

前言

在下首语言是golang,所以会用他作为示例。

原文参见 @arialdomartini的: Back-End Developer Interview Questions

代码示例问题

1. 这段Javascript函数的输出是什么?

function hookupevents() {
  for (var i = 0; i < 3; i++) {
    document.getElementById("button" + i)
      .addEventListener("click", function() { 
        alert(i); 
      });
  }
}

        这段JavaScript代码定义了一个名为hookupevents的函数,该函数的主要作用是为三个ID分别为"button0"、"button1"和"button2"的HTML元素添加点击事件监听器。当这些按钮被点击时,会触发一个匿名函数,该函数会弹出一个警告框显示变量i的值。

        然而,由于闭包的特性,当事件处理函数被实际执行时,它会访问其所在的词法作用域中当时保存的i变量的值,而不是事件绑定时的值。在循环结束后,i的值将是3,因此无论点击哪一个按钮,弹出的警告框都将显示数字3。

        所以,如果执行hookupevents()函数并依次点击这三个按钮,弹出的警告框都会显示数字3。这就是著名的JavaScript闭包陷阱的一个例子。要解决这个问题,可以使用IIFE(立即调用的函数表达式)或其他方式来捕获每个循环迭代时i的值,如下所示:

function hookupevents() {
  for (var i = 0; i < 3; i++) {
    (function(index) {
      document.getElementById("button" + index)
        .addEventListener("click", function() { 
          alert(index); 
        });
    })(i);
  }
}

        通过这种方式,每个按钮的事件处理函数会记住各自绑定时的index值,从而正确显示0、1或2。

2. 关于类型擦除(Type Erasure),这段Java代码的输出是什么?为什么?

ArrayList<Integer> li = new ArrayList<Integer>();
ArrayList<Float> lf = new ArrayList<Float>();
if (li.getClass() == lf.getClass()) // evaluates to true
  System.out.println("Equal");

在Java中,由于类型擦除(Type Erasure)的机制,上述代码段的输出将会是:

Equal

        原因在于Java泛型在编译后的字节码中并不保留具体类型参数信息。在运行时,        ArrayList<Integer>ArrayList<Float>都会变成原始的非泛型类ArrayList。因此,li.getClass()lf.getClass()实际上都是获取到ArrayList类的Class对象,所以在运行时比较这两个类对象时,结果是相等的。

        类型擦除确保了Java泛型的兼容性和运行时