【1】猫眼娱乐后端开发面试题整理

[1]. 全量索引和增量索引的区别

全量索引:检索系统在启动时一次性读取当前数据库中的所有数据,建立索引。

增量索引:系统运行过程中,监控数据库的变化,即增量,实时加载更新,构建索引。

[2]. 解释一下控制反转

控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。

[3]. Spring中的常见注解

Spring Bean相关注解

@SpringBootApplication:一个组合注解,包括了@Configuration、@EnableAutoConfiguration和@ComponentScan三个注解。用于标识SpringBoot应用程序的入口类。

@Component:用于标识一个类是Spring容器中的组件。泛指各种组件,当类不属于@Controller、@Services等的时候,可以使用@Component来标注这个类。

@Autowired:@Autowired注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。如果想按照名称(byName)来装配,可以结合@Qualifier注解一起使用。

AOP相关注解

@Before:前置通知,在方法执行之前执行。

@After:后置通知,在方法执行之后执行。

@Around:环绕通知,围绕着方法执行。

JPA相关注解

@Id:用于标记实体类的主键字段。

@Entity:用于标识一个类是一个JPA实体,对应于数据库中的一个表。

@Transien:用于标记一个字段不被持久化,即不映射到数据库表中。

@Basic:表示一个属性到数据库表的字段的映射,默认情况下所有属性都使用此注解。

Lombok相关注解

@Slf4j:用于在Java类中自动生成日志记录器。

@NoArgsConstructor:注解在类上,为类提供一个无参的构造方法。

@AllArgsConstructor:注解在类上,为类提供一个全参的构造方法。

[4]. 解释一下CAS

CAS(Compare and Swap) 是一种用于实现多线程同步的原子操作,不需要使用传统的锁机制来保证线程安全,可以减少锁的使用,解决了加锁释放锁导致的上下文切换的问题,提高了并发性能。

CAS 操作包含三个操作数:内存地址V,旧的预期值A,计算后要修改后的新值B。在执行操作之前,先比较当前内存V中的值是否等于期望值A,如果相等,则执行修改值为B;如果不相等,则不执行修改操作,继续进行比较,直到内存V中的值与期望值A相等为止。

[5]. 介绍一下锁升级

锁升级的意义在于提高多线程环境下的性能和吞吐量,减少同步操作的开销,并尽量避免线程切换的开销。

锁升级是Java中synchronized关键字实现同步机制时,锁状态随着竞争情况逐渐升级的一个过程。synchronized锁有四种状态,级别从低到高依次是:无锁状态、偏向锁状态、轻量级锁状态和重量级锁状态。

当第一个线程访问同步块并获取锁时,锁从无锁状态升级为偏向锁

当第二个线程尝试获取同一个锁时,如果发现该锁已经是偏向锁,并且偏向的线程仍然存活,则JVM会将锁升级为轻量级锁。如果偏向的线程已经不存在,则第二个线程直接获得偏向锁,无需进行锁升级。

当多个线程竞争同一个轻量级锁时,JVM会将锁升级为重量级锁,并让所有等待锁的线程进入阻塞状态。

[6]. Bean的生命周期

Spring中Bean的生命周期就是Bean在Spring中从创建到销毁的整个过程。

可以划分为五大步:

  • 第一步:实例化Bean
  • 第二步:Bean属性赋值
  • 第三步:初始化Bean
  • 第四步:使用Bean
  • 第五步:销毁Bean

[7]. 介绍一下Java中常用的集合

Java中的集合类主要由单列集合Collection 和双列集合Map 这两个接口派生而出,其中Collection接口又派生出三个子接口,分别是SetListQueue

Set接口表示无序的,元素不可重复的集合,常用的实现类有HashSet和TreeSet;

List接口表示有序的,元素可以重复的集合,常用的实现类有ArrayList和LinkedList;

Queue接口表示先进先出(FIFO)的队列,常用的实现类有LinkedList、PriorityQueue。

Map接口表示具有映射关系(key-value)的集合,常用的实现类有HashMap和TreeMap。

[8]. 线程安全的List集合有哪些

Vector:底层实现和ArrayList一样,所有操作元素的方法都加了synchronized关键字来保证多线程环境中操作时的线程安全,但同时也导致操作Vector的效率非常低。

Collections.synchronizedList:通过Collections.synchronizedList方法包装一个普通的List,使得所有对List的操作都会被同步机制保护,从而保证线程安全。

CopyOnWriteArrayList:CopyOnWriteArrayList通过在写操作时复制底层数组来实现线程安全,适用于读多写少的并发场景。

[9]. 介绍一下Java中基本的数据类型

基本数据类型分为整数类型浮点类型字符类型布尔类型。其中整数类型有byte(1个字节),short(2个字节),int(4个字节),long(8个字节)四个,浮点类型有float(4个字节)、double(8个字节)两个,再加上字符类型char(2个字节)和布尔类型boolean(1个字节)。

[10]. 手撕:判断链表是否有环

法一:快慢指针
java 复制代码
class Main {
    public boolean hasCycle(ListNode head) {
        // 定义快慢指针,初始都指向头节点
        ListNode fast = head;
        ListNode slow = head;
        // 当快指针不为空且快指针的下一个节点不为空时,继续循环
        while (fast != null && fast.next != null) {
            // 快指针每次移动两步
            fast = fast.next.next;
            // 慢指针每次移动一步
            slow = slow.next;
            // 如果快慢指针相遇,说明存在环,返回true
            if (fast == slow) {
                return true;
            }
        }
        // 快慢指针没有相遇,说明不存在环,返回false
        return false;
    }

}
法二:哈希表
java 复制代码
class Main {
     public boolean hasCycle(ListNode head) {
         // 创建一个HashSet集合,用于存储遍历过的节点
         Set<listnode> set = new HashSet<listnode>();
         // 当链表头节点不为空时,继续循环
         while (head != null) {
             // 如果集合中已经存在当前节点,说明链表存在环,返回true
             if (!set.add(head)) {
                 // 返回true,表示链表存在环
                 return true;
             }
             // 将当前节点移动到下一个节点
             head = head.next;
         }
         // 遍历完链表后,未发现环,返回false
         return false;
     }

}
相关推荐
月光水岸New2 小时前
Ubuntu 中建的mysql数据库使用Navicat for MySQL连接不上
数据库·mysql·ubuntu
狄加山6752 小时前
数据库基础1
数据库
我爱松子鱼2 小时前
mysql之规则优化器RBO
数据库·mysql
chengooooooo2 小时前
苍穹外卖day8 地址上传 用户下单 订单支付
java·服务器·数据库
Rverdoser3 小时前
【SQL】多表查询案例
数据库·sql
Galeoto3 小时前
how to export a table in sqlite, and import into another
数据库·sqlite
人间打气筒(Ada)4 小时前
MySQL主从架构
服务器·数据库·mysql
leegong231114 小时前
学习PostgreSQL专家认证
数据库·学习·postgresql
喝醉酒的小白4 小时前
PostgreSQL:更新字段慢
数据库·postgresql
敲敲敲-敲代码4 小时前
【SQL实验】触发器
数据库·笔记·sql