四川汇烁面试总结

2024-05-29 07:04
文章标签 面试 总结 四川 汇烁

本文主要是介绍四川汇烁面试总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

自我介绍+项目介绍、

目录

1.jdk和jre的区别?

2.一段代码的执行流程?

3.接口与抽象类的区别?

4.ArrayList与LinkList的区别?

5.对HashMap的理解?

6.常见的异常?

7.throw 和 throws 有什么区别?

8.try catch finally 每个里面都有return 执行流程?

9.线程池五个线程,交替打印0---100?

10.数据库索引的作用?

11.数据库一条数据只允许一个用户修改,怎么实现?

12.redis的数据会存到硬盘上吗?

13.redis缓存雪崩的解决方案?

14.说一下SpringBoot启动流程?

15.说一下SpringMvc的执行流程?

16.写sql时候的注意事项?

17.MQ怎么保证消息不丢失?

1.jdk和jre的区别?

  • JDK:Java开发工具包,主要用于Java程序的开发。它不仅包含了JRE的全部内容,还提供了编译Java程序所需的工具,如javac编译器和java命令等。
  • JRE:Java运行时环境,主要用于运行Java程序。它包含了Java虚拟机(JVM)和运行Java程序所需的核心类库,但不包含开发工具。

2.一段代码的执行流程?

  1. 编写代码

  2. 编译代码:使用Java编译器(javac命令)将源代码编译成字节码。这个过程会检查语法错误,并生成一个或多个.class文件,这些文件包含了Java虚拟机(JVM)可以理解的指令。

  3. 运行时环境准备:确保系统中安装了Java运行时环境(JRE)或Java开发工具包(JDK),因为它们包含了运行Java程序所需的Java虚拟机(JVM)。

  4. 加载字节码:JVM的类加载器(ClassLoader)负责加载.class文件到内存中。

  5. 验证字节码:JVM的验证器确保加载的字节码是安全和有效的,没有违反JVM规范。

  6. 准备和解析:JVM准备阶段会为类变量分配内存,并设置默认初始值。解析阶段中,JVM将字节码中的符号引用转换为直接引用。

  7. 初始化:静态变量和静态代码块被执行,类变量被初始化为指定的初始值。

  8. 执行主方法:JVM通过反射机制调用包含main方法的类的实例,并执行main方法,这是程序的入口点。

  9. 运行字节码:JVM的执行引擎根据字节码执行程序。字节码可以是解释执行,也可以是即时编译(JIT)成机器码后执行。

  10. 垃圾回收:在程序运行过程中,JVM的垃圾回收器会自动回收不再使用的内存。

  11. 程序结束:当main方法执行完毕,或者通过System.exit()显式退出时,程序结束。

  12. 卸载类:当一个类的所有实例都不再被使用,且没有静态引用时,JVM的类加载器会卸载这个类。

3.接口与抽象类的区别?

  1. 定义

    • 接口:是一个完全抽象的概念,可以包含抽象方法和默认方法(Java 8及以上版本),但不能包含任何实现细节。
    • 抽象类:可以包含抽象方法和具体方法,允许包含实现细节。
  2. 实现

    • 接口:一个类可以实现多个接口,使用implements关键字。
    • 抽象类:一个类只能继承一个抽象类,使用extends关键字。
    • 构造方法

      • 接口:不能包含构造方法。
      • 抽象类:可以包含构造方法。
  3. 变量默认值

    • 接口:在Java 8之前,接口中的变量只能是public static final的常量。从Java 8开始,接口可以包含默认方法和静态方法。
    • 抽象类:可以包含任何类型的变量和方法。
  4. 访问修饰符

    • 接口:默认情况下,接口中的所有方法都是public的,所有变量都是public static final的。
    • 抽象类:可以有多种访问修饰符,如publicprotectedprivate等。
  5. 多继承

    • 接口:支持多继承,一个类可以实现多个接口,有助于解决多重继承的问题。
    • 抽象类:不支持多继承,一个类只能继承一个抽象类。
  6. 使用场景

    • 接口:用于定义一组行为规范,通常用于定义能力或者行为的契约。
    • 抽象类:用于表示一个不完整的类,它可能包含部分实现,通常用于共享代码。
  7. 方法体

    • 接口:在Java 8之前,接口中的方法不能有实现。从Java 8开始,接口可以有默认方法和静态方法。
    • 抽象类:可以包含抽象方法和具体方法。
  8. 初始化

    • 接口:不能被实例化,不能直接创建对象。
    • 抽象类:可以被实例化,但通常不这样做,因为它是不完整的。
  9. 私有方法

    • 接口:Java 9开始支持私有方法和私有静态方法。
    • 抽象类:可以包含私有方法。

4.ArrayList与LinkList的区别?

  1. 内部实现

    • ArrayList:基于动态数组实现,这意味着它维护了一个元素数组,可以快速随机访问任何位置的元素。
    • LinkedList:基于双向链表实现,链表中的每个元素都包含对前一个和后一个元素的引用。
  2. 性能特点

    • ArrayList
      • 优点:提供快速的随机访问,即O(1)时间复杂度的get操作。
      • 缺点:在列表末尾添加元素是O(1),但在列表中间插入或删除元素时,可能需要O(n)时间复杂度,因为需要移动后续所有元素。
    • LinkedList
      • 优点:在列表的任何位置插入或删除元素都非常快速,通常是O(1)时间复杂度,只需要改变相邻元素的链接。
      • 缺点:随机访问元素较慢,因为需要从头开始遍历链表,所以是O(n)时间复杂度。
  3. 内存使用

    • ArrayList:通常使用较少的内存,因为它是连续存储。
    • LinkedList:每个元素都需要额外的内存来存储对前后元素的引用,因此内存使用相对较高。
  4. 线程安全

    • 两者都不是线程安全的。如果需要线程安全,可以使用Collections.synchronizedList()方法包装它们,或者使用Vector(类似于ArrayList)和Stack
  5. 使用场景

    • ArrayList:当你需要频繁随机访问列表中的元素时,使用ArrayList更合适。
    • LinkedList:当你需要频繁在列表中间插入或删除元素时,使用LinkedList更合适。
  6. 实现细节

    • ArrayList:实现了RandomAccess接口,这表明它可以快速随机访问元素。
    • LinkedList:实现了Deque接口,这意味着它可以用作双端队列。
  7. 迭代器

    • ArrayList:迭代器实现为基于索引的迭代,通常更快。
    • LinkedList:迭代器实现为基于节点的迭代,可能稍慢。
  8. 失败快速

    • ArrayList:在迭代过程中,如果列表被修改(除了通过迭代器自身的removeadd),会快速失败。
    • LinkedList:迭代器也支持快速失败,但链表结构可能在修改时更稳定。

总结来说,选择ArrayList还是LinkedList取决于你的具体需求,特别是列表操作的类型和频率。如果需要频繁访问元素,ArrayList是更好的选择;如果需要频繁插入或删除元素,尤其是在列表中间,LinkedList可能更合适。

5.对HashMap的理解?

1. **数组和链表/红黑树**:
   - `HashMap`内部使用一个数组(通常是`Node<K,V>[]`类型的数组)来存储键值对(`Entry`对象)。
   - 当发生哈希冲突时(即两个或多个键具有相同的哈希码),`HashMap`会使用链表来解决冲突。从Java 8开始,当链表的长度超过一定阈值(TREEIFY_THRESHOLD,默认为8)时,链表会转换成红黑树,以提高搜索效率。

2. **哈希函数**:
   - `HashMap`使用键对象的`hashCode()`方法来计算哈希码,然后通过哈希码来确定键值对在数组中的位置。

3. **容量和加载因子**:
   - `HashMap`有一个容量(capacity)的概念,即内部数组的大小。
   - 加载因子(load factor)是一个衡量`HashMap`满的程度的参数,它是一个介于0和1之间的浮点数,默认值为0.75。当实际存储的键值对数量超过数组容量与加载因子的乘积时,`HashMap`会进行扩容。

4. **扩容**:
   - 当键值对的数量达到阈值时,`HashMap`会创建一个容量更大的新数组(通常是原数组大小的两倍),并将原数组中的所有键值对重新映射(rehash)到新数组中。这个过程称为再散列(rehashing)。

5. **再散列**:
   - 在扩容时,`HashMap`会遍历旧数组中的所有键值对,使用新的哈希函数重新计算它们在新数组中的位置。
   - 这个过程是昂贵的,因为它涉及到遍历和复制所有键值对。

6. **树化**:
   - 当链表的长度超过TREEIFY_THRESHOLD时,链表会转换成红黑树。这个转换可以减少查找、插入和删除操作的时间复杂度,从O(n)降低到O(log n)。

7. **哈希碰撞**:
   - 当两个键具有相同的哈希码,并且在数组中映射到同一位置时,会发生哈希碰撞。
   - `HashMap`通过链表或红黑树来解决哈希碰撞。

8. **null键和null值**:
   - `HashMap`允许一个null键和多个null值。

9. **并发问题**:
   - `HashMap`不是线程安全的。如果需要线程安全的HashMap,可以使用`Collections.synchronizedMap()`方法包装它,或者使用`ConcurrentHashMap`。

10. **迭代器**:
    - `HashMap`的迭代器是快速失败的,这意味着在迭代过程中如果检测到`HashMap`被修改,迭代器会立即抛出`ConcurrentModificationException`。

6.常见的异常?

在Java中,异常是程序运行时发生的错误。Java异常处理机制允许程序在发生错误时采取相应的措施,而不是直接崩溃。Java的异常分为两大类:受检异常(checked exceptions)和非受检异常(unchecked exceptions)。

### 受检异常(Checked Exceptions)
受检异常是编译时检查的异常,必须通过`try-catch`块或`throws`子句处理。这些异常通常是可预见的,并且可以恢复。

- **IOException**:当发生I/O错误时抛出,如文件读写错误。
- **SQLException**:数据库操作中发生错误时抛出。
- **FileNotFoundException**:尝试访问不存在的文件时抛出。
- **MalformedURLException**:URL格式不正确时抛出。
- **IndexOutOfBoundsException**:访问数组或集合时索引超出范围时抛出。
- **NumberFormatException**:尝试将字符串转换为数字,但字符串不是适当的格式时抛出。

### 非受检异常(Unchecked Exceptions)
非受检异常是在编译时不强制处理的异常,通常是编程错误导致的。

#### 运行时异常(Runtime Exceptions)
运行时异常是非受检异常的一种,通常由编程错误引起。

- **NullPointerException**:尝试使用了一个未被初始化(null)的对象时抛出。
- **IllegalArgumentException**:方法接收到无效参数时抛出。
- **IllegalStateException**:对象的状态不满足请求的操作时抛出。
- **ArrayStoreException**:尝试将错误类型的对象存储到一个对象数组中时抛出。
- **ClassCastException**:尝试将对象强制转换为不是实例的子类时抛出。
- **ArithmeticException**:算术运算错误时抛出,如除以零。
- **NumberFormatException**:字符串转换为数字格式不正确时抛出。

#### 错误(Errors)
错误是非受检异常的另一种,通常表示严重的程序问题,程序通常无法恢复。

- **OutOfMemoryError**:没有足够的内存时抛出。
- **StackOverflowError**:递归调用太深,导致栈溢出时抛出。
- **VirtualMachineError**:虚拟机严重错误,如内存不足。
- **AssertionError**:断言失败时抛出。

### 其他常见异常
- **Exception**:所有受检异常的超类。
- **RuntimeException**:所有运行时异常的超类。

7.throw 和 throws 有什么区别?

1. **throw**:
   - `throw`关键字用于在代码中手动抛出一个异常。
   - 它可以用来抛出任何类型的异常,包括检查型异常(checked exceptions)和非检查型异常(unchecked exceptions)。
   - `throw`后面通常跟一个异常对象,这个对象是`Throwable`类或其子类的实例。
   - `throw`可以在Java代码的任何地方使用,包括方法体内部。

   示例:
   ```java
   throw new IllegalArgumentException("参数不合法");
   ```

2. **throws**:
   - `throws`关键字用于在方法签名中声明该方法可能会抛出的异常。
   - 它后面跟着的是异常类型,用于告诉调用者该方法可能会抛出的异常类型,调用者需要对这些异常进行处理。
   - `throws`只能用于方法签名中,不能用于代码块内部。
   - 使用`throws`声明的异常是编译时检查的,意味着调用者必须处理这些异常,要么通过`try-catch`块捕获它们,要么进一步使用`throws`声明传递给上层调用者。

   示例:
   ```java
   public void myMethod() throws IOException {
       // 方法体可能会抛出IOException
   }
   ```

总结区别:
- `throw`是抛出异常的动作,而`throws`是方法声明可能会抛出的异常类型。
- `throw`用于代码块中,而`throws`用于方法签名中。
- `throw`抛出的是一个具体的异常实例,`throws`声明的是异常的类型。
- `throws`关键字后面跟的是可能会被抛出的异常列表,用逗号分隔。

8.try catch finally 每个里面都有return 执行流程?

### try 块中的 return
如果在`try`块中执行了`return`语句,那么:
- 会立即终止`try`块的执行,并返回`return`语句指定的值。
- `catch`和`finally`块将不会被执行。

### catch 块中的 return
如果在`catch`块中执行了`return`语句,那么:
- 会立即终止当前`catch`块的执行,并返回`return`语句指定的值。
- 如果有其他的`catch`块,它们将继续执行。
- `finally`块将执行,无论`catch`块中是否有`return`。

### finally 块中的 return
如果在`finally`块中执行了`return`语句,那么:
- 这通常被认为是不好的实践,因为它会覆盖`try`和`catch`块中的`return`语句。
- `finally`块的`return`将立即终止方法的执行,并返回`return`语句指定的值。
- 这意味着即使`try`或`catch`块中有`return`,`finally`块中的`return`也会覆盖它们。

请注意,通常不推荐在`finally`块中使用`return`,因为它会使代码的执行流程变得难以理解和预测,而且可能会隐藏错误。

9.线程池五个线程,交替打印0---100?

public class AlternatePrinting {private final Semaphore semaphore = new Semaphore(1);private final AtomicInteger number = new AtomicInteger(0);public void printNumbers() {for (int i = 0; i < 20; i++) { // 0到19,每个线程打印20个数字try {semaphore.acquire();if (number.get() < 100) {int currentNumber = number.incrementAndGet();System.out.println(Thread.currentThread().getName() + " prints " + currentNumber);}semaphore.release();} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}public static void main(String[] args) {ExecutorService executorService = Executors.newFixedThreadPool(5);AlternatePrinting alternatePrinting = new AlternatePrinting();// 提交任务到线程池,每个线程打印0到19的数字20次for (int i = 0; i < 5; i++) {executorService.submit(alternatePrinting::printNumbers);}// 关闭线程池executorService.shutdown();}
}

在这个例子中,我们使用了一个Semaphore来控制对共享资源(即打印操作)的访问。初始时,Semaphore的许可数量为1,这意味着一次只有一个线程可以执行打印操作。

我们还使用了一个AtomicInteger来控制打印的数字,以确保在多线程环境中数字能够正确地从0递增到100。

每个线程在打印前尝试获取Semaphore的许可,如果成功,则通过AtomicInteger获取下一个要打印的数字,并将其打印出来。打印完成后,线程释放Semaphore的许可,允许其他线程继续执行。

10.数据库索引的作用?

数据结构是B+数 非叶子节点不存储数据,存储指向叶子结点的索引。如果查询的非聚集索引,会进行一次回表查询。

11.数据库一条数据只允许一个用户修改,怎么实现?

加乐观锁,分布式锁。

12.redis的数据会存到硬盘上吗?

Redis的数据可以并且通常会被持久化存储到硬盘上。Redis提供了几种不同的数据持久化选项,以确保即使在服务器崩溃或重启的情况下数据也不会丢失。以下是Redis支持的几种主要持久化方式:

  1. RDB持久化 (Redis Database):

    • 这种形式的持久化会在指定的时间间隔内生成数据集的时间点快照。
    • 通过配置save <seconds> <changes>可以在Redis.conf配置文件中设置自动保存的规则。
    • RDB持久化是通过创建进程的方式来完成的,它会将内存中的数据保存到一个.rdb文件中。
  2. AOF持久化 (Append Only File):

    • AOF持久化记录每次写操作命令,并将其追加到文件末尾。
    • 这提供了更好的数据安全性,因为它减少了在故障情况下可能丢失的数据量。
    • 可以通过配置appendonly yes在Redis.conf中启用AOF持久化。
    • AOF文件以纯文本形式存储,并且可以被手动编辑或通过Redis的LOAD命令加载。
  3. RDB和AOF的组合

    • 可以同时使用RDB和AOF持久化,以获得两者的优点。
    • 例如,可以使用RDB来获得更紧凑的备份文件,并使用AOF来提供更细粒度的数据恢复。
  4. 虚拟内存 (VM):

    • Redis的虚拟内存功能不是持久化机制,但它允许Redis将部分数据交换到磁盘,以减少内存的使用。
    • 这不是真正的持久化,因为数据交换到磁盘上的数据不是持久的,且在Redis重启后不会恢复。
  5. 磁盘快照

    • 在某些部署环境中,可能还会使用外部工具来创建Redis数据的磁盘快照。
  6. 复制

    • 虽然不是持久化机制,但Redis的复制功能可以用来创建数据的热备份,主节点的数据变更会实时复制到从节点。

使用哪种持久化方式取决于具体的应用场景和需求。例如,如果数据安全性是首要考虑因素,可能会选择AOF持久化;如果需要定期的数据备份,可能会选择RDB持久化。在实际部署中,通常会根据需要选择一种或多种持久化策略。

13.redis缓存雪崩的解决方案?

Redis缓存雪崩是指由于大量缓存数据在相近时间内同时过期,导致大量请求直接打到数据库上,从而对数据库造成巨大压力,甚至引起数据库宕机的现象。

  1. 多级缓存机制

    • 使用本地缓存和分布式缓存相结合的方式。当分布式缓存失效时,本地缓存可以作为一个备份,减少对数据库的直接压力。
  2. 预加载和预热缓存

    • 在缓存即将过期前,后台异步更新缓存数据,这样可以避免大量请求同时击中数据库。
  3. 动态调整缓存策略

    • 根据系统负载和业务重要性动态调整缓存失效时间和限流策略。
  4. 设置随机过期时间

    • 避免大量缓存在同一时间过期,通过设置随机的过期时间来分散请求。
  5. 使用缓存标记策略

    • 在标记失效时更新数据缓存,确保缓存的数据是最新的。
  6. 实施多级缓存策略

    • 如一级缓存失效时由二级缓存更新。
  7. 增加自动化监控

    • 确保能在问题发生前及时发现异常。
  8. 限流和降级

    • 在系统负载较高时,通过限流和降级措施来保护后端服务。
  9. 缓存数据的过期时间设置随机

    • 防止同一时间大量数据过期现象发生。
  10. 超热数据使用永久key

    • 对于非常热点的数据,可以设置为永不过期。
  11. 定期维护(自动+人工)

    • 对即将过期数据做访问量分析,确认是否延时,配合访问量统计,做热点数据的延时。
  12. 加锁机制

    • 当缓存中没有数据,第1个进入的线程,获取锁并从数据库去取数据,其他并行进入的线程会等待,这样就防止都去数据库重复取数据,重复往缓存中更新数据情况出现。

通过这些策略,可以有效地预防和应对缓存雪崩,增强系统的稳定性和可靠性。

14.说一下SpringBoot启动流程?

Spring Boot的启动流程是一系列初始化和配置步骤,旨在准备应用程序运行环境并使其准备好处理请求。以下是Spring Boot启动流程的概述:

1. **初始化SpringApplication**:
   - 创建`SpringApplication`实例,它负责启动Spring Boot应用程序。

2. **运行SpringApplication**:
   - 调用`SpringApplication.run()`方法开始启动过程。

3. **加载应用配置**:
   - 加载`application.properties`或`application.yml`等配置文件中的属性。

4. **执行Banner**:
   - 打印启动时的Banner(如果有定义)。

5. **创建并配置ApplicationContext**:
   - 创建Spring应用上下文`ApplicationContext`,它是Spring框架的核心,负责管理Bean的生命周期和依赖关系。

6. **执行Bean定义**:
   - 通过`@ComponentScan`指定的包路径扫描组件,自动注册`@Component`、`@Service`、`@Repository`、`@Controller`等注解的类作为Bean。

7. **加载起步依赖**:
   - 加载`spring-boot-starter`起步依赖中定义的库和配置。

8. **自动配置类的应用**:
   - 根据类路径中的库、配置文件和`@EnableAutoConfiguration`注解,Spring Boot会尝试自动配置应用程序。

9. **注册并执行所有的`CommandLineRunner`和`ApplicationRunner`**:
   - 在Spring应用上下文准备好之后,执行所有的`CommandLineRunner`和`ApplicationRunner`接口实现类,这些接口允许你在应用程序启动后执行自定义代码。

10. **注册所有的Servlet、Filter和ServletListener**:
    - 如果应用程序是一个Web应用程序,Spring Boot会自动注册所有的Servlet、Filter和ServletListener。

11. **初始化Tomcat/Jetty等内嵌服务器**:
    - 如果应用程序是一个Web应用程序,Spring Boot会初始化内嵌的Tomcat或Jetty服务器。

12. **监听端口**:
    - 内嵌服务器开始监听端口,等待外部请求。

13. **应用程序完全启动**:
    - 所有上述步骤完成后,应用程序完全启动,并准备好接收和处理请求。

15.说一下SpringMvc的执行流程?

  1. 客户端发送请求: 用户通过浏览器或客户端工具发送HTTP请求到服务器。

  2. 请求到达DispatcherServlet: HttpServletRequest对象封装了客户端的原始请求,所有进入的请求首先到达中央调度器DispatcherServlet

  3. 请求映射DispatcherServlet根据请求的URL查找相应的处理器映射(Handler Mapping)。处理器映射负责将请求映射到对应的处理器(Controller)。

  4. 执行Controller: 找到映射的Controller后,DispatcherServlet调用Controller中的方法来处理请求。

  5. 返回ModelAndView: Controller执行完成后,通常会返回一个ModelAndView对象,其中包含模型数据(Model)和视图名称(View)。

  6. 视图解析DispatcherServlet使用视图解析器(View Resolver)来解析ModelAndView中的逻辑视图名称,以确定具体的视图实现。

  7. 渲染视图: 视图解析器返回具体的视图对象后,DispatcherServlet将模型数据传递给视图,并渲染最终的视图。

  8. 返回响应: 渲染完成后,DispatcherServlet将视图转换为HTTP响应并发送回客户端。

  9. 更新Web页面: 客户端浏览器接收到响应后,根据响应内容更新Web页面。

在整个流程中,Spring MVC提供了多个扩展点,允许开发者插入自己的逻辑,例如:

  • 拦截器(Interceptors):可以在请求处理前后执行自定义逻辑。
  • 异常处理器(Exception Handlers):可以捕获和处理Controller中抛出的异常。
  • 数据转换器(Converters):用于自动转换请求参数到Java对象。
  • 数据验证器(Validators):用于验证用户输入的数据。

Spring MVC的执行流程是高度可定制的,开发者可以根据需要配置和扩展框架的各种组件。这种灵活性使得Spring MVC成为构建现代Web应用程序的流行选择。

16.写sql时候的注意事项?

尽量使用到索引,避免索引失效,如果接口查询慢,用慢查询日志和explain来定位慢SQL,优化性能。

17.MQ怎么保证消息不丢失?

  1. 持久化存储

    • 消息队列通常提供持久化选项,将消息存储在磁盘上而不仅仅是内存中。这样即使系统崩溃,消息也不会丢失。
  2. 消息确认(Acknowledgements)

    • 消费者在成功处理消息后发送一个确认回执给MQ。只有在收到确认后,MQ才会认为消息已被成功消费并将其从队列中移除。
  3. 重试机制

    • 如果消费者处理消息失败,MQ可以配置为自动重试,将消息重新放入队列中,等待再次消费。
  4. 死信队列(Dead Letter Queues)

    • 对于无法处理的消息,可以发送到一个特殊的队列(死信队列),而不是简单地丢弃,这样可以进行问题排查和消息恢复。

这篇关于四川汇烁面试总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1012975

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

字节面试 | 如何测试RocketMQ、RocketMQ?

字节面试:RocketMQ是怎么测试的呢? 答: 首先保证消息的消费正确、设计逆向用例,在验证消息内容为空等情况时的消费正确性; 推送大批量MQ,通过Admin控制台查看MQ消费的情况,是否出现消费假死、TPS是否正常等等问题。(上述都是临场发挥,但是RocketMQ真正的测试点,还真的需要探讨) 01 先了解RocketMQ 作为测试也是要简单了解RocketMQ。简单来说,就是一个分

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

秋招最新大模型算法面试,熬夜都要肝完它

💥大家在面试大模型LLM这个板块的时候,不知道面试完会不会复盘、总结,做笔记的习惯,这份大模型算法岗面试八股笔记也帮助不少人拿到过offer ✨对于面试大模型算法工程师会有一定的帮助,都附有完整答案,熬夜也要看完,祝大家一臂之力 这份《大模型算法工程师面试题》已经上传CSDN,还有完整版的大模型 AI 学习资料,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

二分最大匹配总结

HDU 2444  黑白染色 ,二分图判定 const int maxn = 208 ;vector<int> g[maxn] ;int n ;bool vis[maxn] ;int match[maxn] ;;int color[maxn] ;int setcolor(int u , int c){color[u] = c ;for(vector<int>::iter

整数Hash散列总结

方法:    step1  :线性探测  step2 散列   当 h(k)位置已经存储有元素的时候,依次探查(h(k)+i) mod S, i=1,2,3…,直到找到空的存储单元为止。其中,S为 数组长度。 HDU 1496   a*x1^2+b*x2^2+c*x3^2+d*x4^2=0 。 x在 [-100,100] 解的个数  const int MaxN = 3000

状态dp总结

zoj 3631  N 个数中选若干数和(只能选一次)<=M 的最大值 const int Max_N = 38 ;int a[1<<16] , b[1<<16] , x[Max_N] , e[Max_N] ;void GetNum(int g[] , int n , int s[] , int &m){ int i , j , t ;m = 0 ;for(i = 0 ;

go基础知识归纳总结

无缓冲的 channel 和有缓冲的 channel 的区别? 在 Go 语言中,channel 是用来在 goroutines 之间传递数据的主要机制。它们有两种类型:无缓冲的 channel 和有缓冲的 channel。 无缓冲的 channel 行为:无缓冲的 channel 是一种同步的通信方式,发送和接收必须同时发生。如果一个 goroutine 试图通过无缓冲 channel

9.8javaweb项目总结

1.主界面用户信息显示 登录成功后,将用户信息存储在记录在 localStorage中,然后进入界面之前通过js来渲染主界面 存储用户信息 将用户信息渲染在主界面上,并且头像设置跳转,到个人资料界面 这里数据库中还没有设置相关信息 2.模糊查找 检测输入框是否有变更,有的话调用方法,进行查找 发送检测请求,然后接收的时候设置最多显示四个类似的搜索结果