智联平台-成都双流阳光融合-互联网医院(北京分公司)**
技术一面问题
1. 策略模式在项目中是如何实现的?
答:策略模式是一种设计模式,它主要用于解决在运行时选择不同算法的问题。在项目中,我们可以用策略模式来避免使用大量的if-else语句,实现可扩展性和灵活性。
在策略模式中,我们首先定义一个策略接口,用于表示一个算法。然后,我们可以定义不同的实现类,每个实现类都代表一个具体的算法。这些实现类都实现了策略接口。
在项目中,我们通常会使用工厂模式或依赖注入来动态选择不同的策略实现类。例如,我们可以根据用户的角色或操作权限动态地选择不同的算法实现类。
另外,我们还可以使用配置文件或数据库来存储不同的算法实现类,在运行时根据配置来选择不同的实现类。
总之,策略模式是一种非常实用的设计模式,可以帮助我们更好地组织代码,提高可扩展性和灵活性。在项目中合理应用策略模式可以让我们的代码更加清晰和易于维护。
2. 针对登录验证中的 JWT+RSA 非对称加密是如何实现的?
答:JWT(JSON Web Token)是一种用于在网络上传递声明的开放标准,通常用于用户身份验证和授权。JWT通过将数据进行签名的方式保证了数据的完整性和真实性。而RSA(Rivest–Shamir–Adleman)非对称加密算法则是一种常用的公钥加密算法,在加密和数字签名领域得到了广泛的应用。
在采用 JWT+RSA 非对称加密进行登录验证时,一般的流程如下:
-
用户在客户端输入用户名和密码,服务端进行验证。
-
如果验证通过,服务端生成一个 JWT,其中包含用户的要求。
-
服务端使用 RSA 非对称加密算法将 JWT 进行签名,得到一个签名字符串。
-
服务端将签名字符串和 JWT 返回给客户端。
-
客户端在发送请求时将 JWT 和签名字符串添加到请求头中,服务端通过 RSA 非对称解密算法验证签名,校验 JWT 的完整性和真实性。
在以上流程中,通过使用 RSA 非对称加密算法进行签名和校验 JWT,在不共享密钥的情况下,有效的保证了 JWT 真实有效性和完整性的互认。
需要注意的是,RSA 非对称加密算法的实现,应避免私钥被泄露,否则将对系统的安全性造成极大威胁。同时,为了保证解密的正确性,应保证服务端和客户端使用的公钥和私钥的匹配。
3. RabbitMQ在项目中的架构是怎样的,以及有哪些消息队列?
RabbitMQ是一个开源的消息中间件,采用Erlang语言编写,实现了AMQP(高级消息队列协议)。在项目中,RabbitMQ主要负责系统解耦、同步改异步、请求消峰等功能。它的架构包括生产者、消费者、交换机和队列。生产者负责生产消息并将其投递到队列中,消费者则从队列中获取并处理消息。
此外,在一些特定的应用场景下,RabbitMQ还支持使用延迟队列和备份队列来实现更复杂的业务需求。例如,在在线考试系统中,考生提交试卷后,如果遇到掉线或者其他情况未能在规定时间内交卷的,系统可以默认交卷并计算成绩和题目入库,并通过微信告诉学生,您的试卷已经自动提交。
在实际项目中,许多知名项目都选择了RabbitMQ作为其消息中间件,如OpenStack、Spring、Logstash等。同时,腾讯云在开发云消息队列系统(CMQ)时,也对RabbitMQ进行了大量的学习和优化,包括瓶颈分析、内存管理、参数调优等。
4. 集合的分类,LinkList在项目中的应用有哪些?
集合主要分为List、Set和Map三类。其中,LinkedList是Java中的一种数据结构,它是一个双向链表,实现了List以及Deque的双向链表,元素允许为null。因此,LinkedList同时具备List以及Deque的特性。
具体来说,LinkedList内部定义了三个变量:size(集合的长度)、first(双向链表头部节点)和last(双向链表尾部节点)。对于频繁操作前后两端的集合来说,具有一些直观的方法,比如add first,remove first,add last,remove last,poll,pop,peek,peek first,peek last,poll first,poll last等。另外,因为LinkedList内部实现上是个链表,所以可以把它当作链表使用。同样还可以代替Stack类当做栈来使用(官方也推荐这么做)。
三、其他电话面试
1. 线程的创建方式?
答:Java 中的线程可以通过三种方式来创建:
- 继承 Thread 类:直接继承 Thread 类并重写 run() 方法来自定义线程。
class MyThread extends Thread {
public void run() {
// 线程执行的逻辑
}
}
// 创建并启动线程
MyThread mt = new MyThread();
mt.start();
- 实现 Runnable 接口:实现 Runnable 接口并重写 run() 方法同时将其传入 Thread 类中。
class MyThread implements Runnable{
public void run() {
// 线程执行的逻辑
}
}
// 创建并启动线程
Thread t = new Thread(new MyThread());
t.start();
- 使用 Callable 和 Future 接口:Callable 接口类似于 Runnable 接口,不同之处在于 callable 的 call() 方法可以返回线程执行的结果。
class MyCallable implements Callable<Integer> {
public Integer call() {
// 线程执行的逻辑
return 1;
}
}
// 创建并启动线程
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Integer> future = executor.submit(new MyCallable());
Integer result = future.get();
以上三种线程创建方式各有优缺点,需要根据具体场景进行选择。通常情况下,应该尽量避免使用第一种方式,因为它会限制类的继承层次,并且可以通过实现 Runnable 接口来将代码和线程分离。第二种方式更加推荐,因为它可以从多个线程中重复使用代码,并且可以避免类的多重继承问题。第三种方式通常用于需要线程返回值的场景,但由于需要等待线程执行完毕才能获得返回结果,所以对系统的响应速度有一定影响。
2. 线程的5大状态?
答:Java 中的线程一共有 5 种状态,分别是:
-
新建状态(New):当使用 new 关键字创建一个线程对象时,即为新建状态。此时线程还没有开始运行,线程对象的 start() 方法也没有被调用。
-
就绪状态(Runnable):当调用线程对象的 start() 方法之后,线程会进入到就绪状态。此时,线程已经准备好要被运行,只等待 CPU 分配时间片。
-
运行状态(Running):当获得 CPU 时间片后,线程开始执行 run() 方法,此时为运行状态。在运行状态中,线程可能因为某些原因导致暂停,如 I/O 操作等。
-
阻塞状态(Blocked):当线程暂停执行后,可能会由于某些原因无法继续执行,例如等待锁的释放、等待用户输入等待 I/O 操作等。此时线程会进入阻塞状态并等待被唤醒。
-
死亡状态(Dead):当线程的 run() 方法执行完毕时,该线程将进入死亡状态。线程也可以通过调用 stop() 方法或发生异常来进入死亡状态。
以上是 Java 线程的 5 种状态,线程可以在这些状态之间进行切换,通常情况下,线程的状态是不可控的,具体取决于系统的调度和执行。在使用多线程编程时,需要注意对线程状态的正确判断和处理,防止出现并发问题和死锁等情况。
3. 项目是如何打包部署的,是如何测试的
Java项目的打包、部署和测试流程通常如下:
-
使用IDEA等开发工具编写代码,并进行单元测试。在IntelliJ IDEA中,可以使用Maven进行项目构建和管理,支持一键打包和部署。
-
完成代码编写后,通过Maven进行项目的打包操作。在项目的根目录下,运行命令
mvn clean package -Dmaven.test.skip=true
即可完成打包。如果代码通过了编译和单元测试,那么它就被打包成可分发和部署的格式了。 -
打包完成后,就可以将生成的jar文件通过scp或者其他工具上传到服务器上。
-
最后,在服务器上运行这个jar文件,启动应用。然后针对应用的各项功能进行系统测试和性能测试,确保其在实际环境中的稳定性和可靠性。
-
经过测试无误后,可以将应用部署到正式环境,并进行上线操作。此时,还需要对系统进行日常的监控和维护,包括系统的更新、备份以及故障处理等工作。
4. Java操作Excel的报表技术POI有21了解吗?
答:是的,Apache POI 是一个开源的 Java API 库,可以用于读写 Microsoft Office 格式的文档,例如 Excel、Word、PowerPoint 等。POI 提供了多种操作 Excel 的方式,其中包括 HSSF(Horrible Spreadsheet Format)、XSSF(XML Spreadsheet Format)和 SXSSF(Streaming usermodel API)等多种实现方式,同时还支持对 Excel 文件的格式化和样式设置等操作。
近期 Apache POI 更新到了 5.0.0 版本,支持了对 Office Open XML (OOXML) 文件格式的完全支持,提供了更好的性能和稳定性。
具体来说,POI 中提供了大量的类和方法,例如 HSSFWorkbook、XSSFWorkbook、Sheet、Row、Cell 等,开发者可以通过这些类和方法来操作 Excel 文件。例如,读取 Excel 文件可以使用以下代码:
// 打开 Excel 文件
FileInputStream inputStream = new FileInputStream(new File("workbook.xlsx"));
// 创建工作簿对象
Workbook workbook = new XSSFWorkbook(inputStream);
// 获取工作表对象
Sheet sheet = workbook.getSheetAt(0);
// 遍历工作表并输出每个单元格的值
for (Row row : sheet) {
for (Cell cell : row) {
System.out.print(cell.getStringCellValue() + "\t");
}
System.out.println();
}
// 关闭工作簿和输入流
workbook.close();
inputStream.close();
这段代码中,使用 XSSFWorkbook 类来创建工作簿对象,使用 getSheetAt() 方法获取工作表对象,遍历工作表并输出每个单元格的值。通过 POI,我们可以方便地读取和写入 Excel 文件,从而实现对数据的报表分析和统计等操作。