面试题整理

面试题整理

JS 遍历数组的方式

// 假设我们有一个数组作为示例
const array = [1, 2, 3, 4, 5];

// 1. 使用 for 循环遍历数组
for (let i = 0; i < array.length; i++) {
    console.log(`for循环: ${array[i]}`);
}

// 2. 使用 forEach 方法遍历数组
array.forEach(function(item, index) {
    console.log(`forEach方法: 索引${index}的值为${item}`);
});

// 3. 使用 for...of 循环遍历数组 (ES6+)
for (let item of array) {
    console.log(`for...of循环: ${item}`);
}

// 4. 使用 map 方法创建一个新数组,这里只是演示,不打印
const doubledArray = array.map(item => item * 2);
console.log(`map方法创建的新数组: ${doubledArray}`);

// 5. 使用 filter 方法筛选出符合条件的元素,这里只是演示,不打印
const filteredArray = array.filter(item => item > 3);
console.log(`filter方法筛选后的数组: ${filteredArray}`);

// 6. 使用 reduce 方法累加数组中的所有元素
const sum = array.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
console.log(`reduce方法计算的总和: ${sum}`);

// 7. 使用 some 和 every 方法检查条件
const hasLargeNumber = array.some(item => item > 4); // 至少有一个大于4的数
const allArePositive = array.every(item => item >= 0); // 所有数都是非负的

console.log(`some方法检查结果(是否有大于4的数字): ${hasLargeNumber}`);
console.log(`every方法检查结果(是否全都是非负数): ${allArePositive}`);

// 8. 使用 while 循环遍历数组
let i = 0;
while (i < array.length) {
    console.log(`while循环: ${array[i]}`);
    i++;
}

// 9. 使用 do...while 循环遍历数组
let j = 0;
do {
    console.log(`do...while循环: ${array[j]}`);
    j++;
} while (j < array.length);

// 注意:通常不推荐使用 for...in 遍历数组,因为它会遍历所有可枚举属性,包括原型链上的属性。

Java中遍历数组的方式

public class ArrayTraversalExample {
    public static void main(String[] args) {
        // 定义一个整型数组用于演示
        int[] intArray = {1, 2, 3, 4, 5};
        Integer[] objectArray = {1, 2, 3, 4, 5}; // 对象数组用于某些方法

        // 1. 传统的for循环
        System.out.println("Traditional for loop:");
        for (int i = 0; i < intArray.length; i++) {
            System.out.println(intArray[i]);
        }

        // 2. 增强型for循环(For-Each)
        System.out.println("Enhanced for loop:");
        for (int element : intArray) {
            System.out.println(element);
        }

        // 3. while循环
        System.out.println("While loop:");
        int i = 0;
        while (i < intArray.length) {
            System.out.println(intArray[i]);
            i++;
        }

        // 4. do-while循环
        System.out.println("Do-while loop:");
        int j = 0;
        do {
            System.out.println(intArray[j]);
            j++;
        } while (j < intArray.length);

        // 5. 使用迭代器(Iterator)
        System.out.println("Using Iterator:");
        List<Integer> list = Arrays.asList(objectArray);
        Iterator<Integer> iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }

        // 6. 使用Stream API(Java 8及以上)
        System.out.println("Using Stream API:");
        Arrays.stream(intArray).forEach(System.out::println);
        // 或者对于对象数组
        Stream.of(objectArray).forEach(System.out::println);

        // 7. 使用Arrays类的静态方法
        System.out.println("Using Arrays.toString():");
        System.out.println(Arrays.toString(intArray));
    }
}

UNION和UNION ALL的区别

UNIONUNION ALL 是 SQL 中用于合并两个或多个 SELECT 语句结果集的关键字。它们的主要区别在于处理重复数据的方式:

  1. UNION:
    • 当使用 UNION 时,它会自动去除两个(或多个)查询结果集中相同的行,确保最终结果集中的每一行都是唯一的。
    • 这意味着 UNION 会在内部执行一个去重操作,这通常需要更多的处理时间和资源,尤其是在处理大型数据集时。
  2. UNION ALL:
    • UNION ALL 不会去除重复的行,它只是简单地将两个结果集合并在一起,保留所有的重复项。
    • 因为没有去重的操作,所以 UNION ALL 的执行速度通常比 UNION 更快,并且消耗的系统资源更少。

联合查询调优


JS如何如何发送请求到后端

var xhr = new XMLHttpRequest();
xhr.open("GET", "http://example.com/api/data", true);
xhr.onreadystatechange = function () {
    if (xhr.readyState == 4 && xhr.status == 200) {
        console.log(xhr.responseText);
    }
};
xhr.send();

SpringBoot的配置文件有几种形式

  • application.properties:这是最常见和最基本的配置方式,使用键值对的形式来定义配置项

  • application.yml 或 application.yaml:AML 是一种人类可读的数据序列化标准,适合表达层次结构数据。相比 .properties 文件,它在处理层级关系时更为简洁

  • 外部配置文件:你可以将配置文件放置在应用程序外部的位置,这样可以方便地在不同环境中切换配置而无需重新打包应用程序。可以通过命令行参数指定配置文件的位置

  • 环境变量:可以直接通过操作系统的环境变量或云平台提供的环境变量来设置配置项。这种方式非常适合于部署到云端或容器化的应用中

  • 命令行参数:启动应用程序时,可以在命令行上直接传递参数给Spring Boot应用

  • JVM系统属性:你也可以通过JVM参数来传递配置信息

  • 随机值生成:对于一些不需要精确控制的配置项,如密钥等,可以使用内置的随机值生成器

  • Profile-specific 配置文件:为了支持多环境配置(开发、测试、生产等),Spring Boot 提供了 profile-specific 的配置文件机制。例如,application-dev.propertiesapplication-prod.yml 可以分别用于开发环境和生产环境

  • @ConfigurationProperties 注解类:可以创建一个Java类,并使用 @ConfigurationProperties 注解来绑定配置文件中的属性

  • SPRING_APPLICATION_JSON 环境变量:可以通过设置 SPRING_APPLICATION_JSON 环境变量来提供JSON格式的配置


优先级
  • ASP.NET Core:配置源按照它们被添加到 ConfigurationBuilder 的顺序进行覆盖,即后配置的覆盖先配置的。
  • Spring Boot:具有固定的优先级规则,某些配置源总是会覆盖其他特定的配置源,而不论它们是如何或何时被添加的。

相比之下,Spring Boot 使用了一个固定的优先级规则来决定哪个配置源应该覆盖其他配置源。如前所述,Spring Boot 有明确的配置源优先级顺序,并且这个顺序是不可变的。

  1. 命令行参数 (--key=value)
    • 直接在启动应用程序时通过命令行提供的参数。
  2. 来自 SPRING_APPLICATION_JSON 的属性(嵌入在环境变量或系统属性中)
    • 例如:SPRING_APPLICATION_JSON='{"key":"value"}'
  3. ServletConfig 初始化参数
    • 如果你的应用是一个Web应用,那么可以通过ServletConfig设置初始化参数。
  4. ServletContext 初始化参数
    • 类似于ServletConfig参数,但是针对整个Web应用程序上下文。
  5. JNDI 属性 (java:comp/env)
    • Java Naming and Directory Interface, 用于查找命名和目录服务中的资源。
  6. Java 系统属性 (System.getProperties())
    • 使用 -D 参数传递给 JVM 的系统属性。
  7. 操作系统环境变量
    • 操作系统级别的环境变量。
  8. 随机值 (random.* )
    • Spring Boot 内置的随机值生成器,如 ${random.value}${random.int} 等。
  9. 打包外部配置文件
    • 包括但不限于 application.propertiesapplication.yml 文件,这些文件位于标准位置之外,并通过 spring.config.location 指定。
  10. 打包内部配置文件
    • 包含在应用程序jar包内的 application-{profile}.propertiesapplication-{profile}.yml 文件。
  11. @Configuration 类上的 @PropertySource 注解
    • 在Spring配置类上使用 @PropertySource 来指定额外的属性文件。
  12. 默认属性 (由 SpringApplication.setDefaultProperties 指定)
    • 应用程序启动时通过编程方式设置的默认属性。

SpringBoot 的配置文件生效位置

  1. 当前目录的 /config 子目录:这是为了方便开发和测试而提供的一个默认位置。
  2. 当前目录:直接放置在应用程序启动路径下的配置文件也会被自动读取。
  3. 类路径中的 /config:对于打包的应用程序,这通常是 src/main/resources/config 目录。
  4. 类路径根目录:通常是指 src/main/resources 目录。

这些位置按照优先级从高到低排列,意味着如果同一个配置项存在于多个位置,则较高优先级位置中的配置会覆盖较低优先级位置中的配置。