Zer0e's Blog

2024面试复盘8

字数统计: 2.9k阅读时长: 10 min
2024/08/01 Share

复盘

反射是什么 怎么用

刚开始我愣了一下,在大学的时候我其实也写过关于反射的文章,结果忘得差不多了。

其实就是借助class对象获取类信息的方式称作反射。

1
2
3
4
5
6
//1
Class c1 = Cat.class; //任何类都有隐含的静态成员class用于获取Class对象
//2
Class c2 = cat.getClass();//实例有一个getClass方法获取Class对象
//3
Class c3 = Class.forName("Cat");

如果使用getMethods则可以获取所有方法。但是getMethod和getMethods获取的是public方法,如果需要获得私有方法,则使用getDeclaredMethod方法。

获取成员则是使用getField/getDeclaredField.

获取构造器是getConstructor/getDeclaredConstructor

Java中的常用集合 底层结构

Java 集合,也叫作容器,主要是由两大接口派生而来:一个是 Collection接口,主要用于存放单一元素;另一个是 Map 接口,主要用于存放键值对。对于Collection 接口,下面又有三个主要的子接口:ListSetQueue

ArrayList底层是Object[] 数组。动态进行扩容。

TreeSet底层是红黑树。

用redis实现延迟队列

使用sortedSet来实现

添加任务:使用ZADD命令将任务添加到有序集合中,分数为任务的执行时间。

消费任务:使用ZRANGEBYSCORE命令获取到期的任务,并使用ZREM命令从有序集合中删除这些任务。

CAP理论

一致性(Consistency)、可用性(Availability)和分区容忍性(Partition Tolerance)。

根据CAP定理,在一个分布式系统中,最多只能同时满足这三个属性中的两个。

一致性(Consistency)

  • 在一个分布式系统中,一致性指的是所有节点在同一时间看到的数据是相同的。换句话说,每次读操作都能够返回最近一次写操作的结果。

可用性(Availability)

  • 可用性指的是系统在任何时间都是可用的,并且每个请求都能够得到非错误的响应(不保证返回最新的数据)。即使某些节点发生故障,系统仍然能够响应请求。

分区容忍性(Partition Tolerance)

  • 分区容忍性指的是系统能够继续操作,即使网络分区(Partition)发生了。网络分区是指网络中的一些节点无法与其他节点通信,但系统仍然能够正常工作。

CA(Consistency and Availability)

  • 系统在正常操作时保证一致性和可用性,但在网络分区时无法容忍。
  • 例子:传统的关系型数据库(如单一的SQL数据库)。

CP(Consistency and Partition Tolerance)

  • 系统在网络分区时保证一致性,但可能会牺牲部分可用性。
  • 例子:一些分布式数据库(如HBase、MongoDB在强一致性配置下)。

AP(Availability and Partition Tolerance)

  • 系统在网络分区时保证可用性,但可能无法保证强一致性。
  • 例子:一些NoSQL数据库(如Cassandra、DynamoDB)。

分布式锁实现

有redis分布式锁和mysql的悲观锁。

使用SET命令以NXEX选项来设置锁键。

使用DEL命令来释放锁。

使用一个唯一的值(通常是UUID)来标识锁持有者,以防止误删他人的锁。

NX 选项

  • 含义NX选项表示”只在键不存在时设置”(Not Exists)。
  • 功能:当NX选项指定时,SET命令只会在键不存在的情况下设置键值。如果键已经存在,SET命令不会执行任何操作。
  • 用途:常用于分布式锁的实现,确保只有一个客户端能够成功设置锁,防止多个客户端同时获得锁。

EX 选项

  • 含义EX选项表示”设置键的过期时间”(Expire)。
  • 功能:当EX选项指定时,SET命令会在设置键值的同时,为键设置一个过期时间(以秒为单位)。键在过期时间到达后将自动删除。
  • 用途:用于设置键的自动过期,防止因持有锁或设置值过长时间而导致系统资源泄漏。对于分布式锁,设置锁的过期时间非常重要,以确保锁不会无限期地占用,导致系统无法恢复。

死锁与避免

在计算机系统中,死锁的发生通常需要满足以下四个条件,这四个条件被称为死锁的必要条件:

  1. 互斥(Mutual Exclusion):资源不能被多个进程(或线程)同时占用,即资源在某一时刻只能被一个进程(或线程)使用。
  2. 占有并等待(Hold and Wait):进程(或线程)已经持有一个或多个资源,并且正在等待其他资源,而这些资源被其他进程(或线程)持有。
  3. 非抢占(No Preemption):已经分配给进程(或线程)的资源在被释放之前不能被抢占,资源只能在进程(或线程)自愿释放后才能被其他进程(或线程)获取。
  4. 循环等待(Circular Wait):存在一个进程(或线程)集合,其中每个进程(或线程)都在等待下一个进程(或线程)释放资源,形成一个循环链。

预防就是破坏四个条件。

避免可以使用银行家算法:在资源请求时,通过检查是否能保证系统处于安全状态来决定是否分配资源。只有在分配资源后系统仍然处于安全状态时,才允许该资源分配。

检测使用资源分配图(Resource Allocation Graph)或其他检测机制来检测系统中是否存在死锁。

恢复

  • 终止进程:选择一个或多个进程终止,以释放资源。
  • 资源抢占:从某些进程中抢占资源,分配给其他进程,以打破死锁循环。

git切换分支? 复制某个commit?

平常git用的不多。只回答上第一个。

使用git checkout来切换分支。

如果你想从某个特定的提交创建一个新的分支:

1
2
3
git checkout -b <new-branch-name> <commit-hash>
或者
git switch -c <new-branch-name> <commit-hash>

如果你想将某个提交的更改应用到当前分支,可以使用git cherry-pick

1
git cherry-pick <commit-hash>

maven怎么解决依赖冲突

使用mvn dependency:tree查看冲突依赖,然后在pom文件中使用<exclusions>排除依赖。

也可以在pom.xml文件中,通过<dependencyManagement>标签来强制使用特定版本的依赖。

使用mvn dependency:analyze这个命令可以识别未使用和未声明的依赖。

对称加密和非对称加密算法?有什么优缺点

对称加密是指加密和解密使用相同的密钥。常见的对称加密算法有AES(Advanced Encryption Standard)、DES(Data Encryption Standard)和3DES(Triple DES)。

优点

  1. 速度快:对称加密算法通常比非对称加密算法快,因为它们的计算复杂度较低,适合处理大量数据。
  2. 效率高:对称加密适用于需要高性能加密的场景,如大数据传输、磁盘加密等。
  3. 资源消耗少:对称加密的计算资源消耗通常较低,因此适合在资源有限的环境中使用。

缺点

  1. 密钥管理困难:对称加密需要确保密钥的安全传输和存储,密钥的分发和管理是一个挑战。

  2. 不适合分布式系统:在大规模分布式系统中,密钥的管理和分发变得更加复杂,需要额外的机制来确保安全性。

  3. 密钥泄露风险:一旦密钥泄露,所有用该密钥加密的数据都可能被解密,因此密钥的保护至关重要。

非对称加密(或称公钥加密)使用一对密钥:公钥和私钥。公钥用于加密,私钥用于解密。常见的非对称加密算法有RSA(Rivest–Shamir–Adleman)、ECC(Elliptic Curve Cryptography)和DSA(Digital Signature Algorithm)。

优点

  1. 密钥管理简化:非对称加密解决了密钥分发的问题。公钥可以公开,而私钥保持秘密。
  2. 数字签名:非对称加密支持数字签名,可以验证数据的真实性和完整性。
  3. 加密密钥交换:常用于安全的密钥交换,例如在HTTPS中使用非对称加密来安全地交换对称加密密钥。

缺点

  1. 速度较慢:非对称加密通常比对称加密慢,因为它需要更复杂的数学运算,适合加密小量数据。
  2. 资源消耗大:计算和存储资源消耗较高,因此不适合大规模数据的加密。
  3. 计算复杂性:非对称加密的算法复杂度较高,实施和优化可能较为复杂。

spring框架有什么设计模式?aop用的是什么?

单例模式:通过配置Bean的作用域为singleton(默认值),Spring在启动时创建唯一的Bean实例。

代理模式:Spring使用代理模式来实现AOP(面向切面编程)。通过动态代理或CGLIB字节码生成,Spring可以在运行时创建代理对象,并在方法调用前后插入额外的逻辑(如事务管理、日志记录等)。

模板方法模式: Spring的JdbcTemplateJmsTemplateHibernateTemplate等类使用模板方法模式来简化常见的操作。模板方法模式定义了操作的算法框架,将某些步骤的实现延迟到子类。

工厂模式:Spring使用工厂模式来创建Bean实例。Bean的创建由Spring容器负责,开发者只需要定义Bean的配置,Spring容器在运行时根据配置创建和管理Bean。

策略模式: Spring的许多组件使用策略模式来定义算法的变体,而不需要修改客户端代码。例如,Spring的TransactionManager接口允许不同的事务策略实现,如DataSourceTransactionManagerJpaTransactionManager等。

观察者模式:Spring的事件发布和监听机制使用了观察者模式。Spring允许应用程序通过事件发布和监听来实现松耦合的组件交互。ApplicationEventApplicationListener接口,ApplicationContext作为事件发布者,监听器作为观察者。

装饰器模式:Spring AOP的一个实现,特别是ProxyFactoryBean,使用了装饰器模式来增强对象的功能,而不需要改变其结构。通过在代理对象上添加额外的功能来装饰原始对象。Spring AOP中的切面(Aspect)和建议(Advice)可以看作是对目标对象的装饰。

算法题

输入一个字符串n1, 由数字与”,”分隔,输出这个序列中第二大的数字,以字符串返回。

还算比较简单,就是先切分字符串,然后用Integer.valueOf变成数字,然后用两个变量记录最大和第二大的数字。

面试时写的时候忘记考虑没有第二大的数字了。现在让GPT又写了一下才恍然大悟。

1
2
3
4
5
6
7
8
9
10
11
12
13
// 找到最大的和第二大的数字
Integer largest = null;
Integer secondLargest = null;

for (Integer number : uniqueNumbers) {
if (largest == null || number > largest) {
secondLargest = largest;
largest = number;
} else if (secondLargest == null || (number > secondLargest && number < largest)) {
secondLargest = number;
}
}
return (secondLargest != null) ? String.valueOf(secondLargest) : null;

总结

没想到都是八股文,措手不及,其中最后一个aop用的是什么设计模式我竟然转不过脑子来。

也有一些没答出来,比如chery-pick,反射也答得不好,sortedSet如何删除也没答出来。

包括代码编写只面试了半个小时,不知道咋说,准备下一场其他面试吧。。

CATALOG
  1. 1. 复盘
    1. 1.1. 反射是什么 怎么用
    2. 1.2. Java中的常用集合 底层结构
    3. 1.3. 用redis实现延迟队列
    4. 1.4. CAP理论
    5. 1.5. 分布式锁实现
      1. 1.5.1. NX 选项
      2. 1.5.2. EX 选项
    6. 1.6. 死锁与避免
    7. 1.7. git切换分支? 复制某个commit?
    8. 1.8. maven怎么解决依赖冲突
    9. 1.9. 对称加密和非对称加密算法?有什么优缺点
    10. 1.10. spring框架有什么设计模式?aop用的是什么?
    11. 1.11. 算法题
  2. 2. 总结