答了布隆过滤,然后问重点怎么加载到内存中
同步阻塞,同步非阻塞,异步IO,IO多路复用
举个简单的例子方便大家理解,假设我们在超时里买东西,阻塞和非阻塞区别在于我们结账的时候是排队等待,还是在等待的时候还做其他的事情,阻塞就是我们只能排队等着,非阻塞就是指我们在排队的时候还能玩手机,同步和异步则是收银员是要一直等待机器出信息还是说在等待机器出结账信息的时候能做别的事情。
同步阻塞 | 同步非阻塞 | IO多路复用 | 异步IO | |
优点 | 程序开发简单;在阻塞等待数据期间,用户线程挂起,不占用CPU资源 | 内核缓冲区没有数据的情况下,发起的系统调用不会阻塞,用户程序不会阻塞,实时性较好 | select/epoll可以同时处理成百上千的连接,与之前的一个线程维护一个连接相比,IO多路复用则不需要创建线程,也就不需要维护,从而减少系统开销 | 在内核等待数据和复制数据的两个阶段,用户线程都不是阻塞的 |
缺点 | 一个线程维护一个IO流的读写,在高并发应用场景下,需要大量的线程来维护大量的网络连接,内存、线程切换开销会十分巨大 | 需要不断地重复地发起IO调用,这种不断轮询,不断询问内核的方式,会占用CPU大量的时间,资源利用率比较低 | select/epoll系统调用,属于阻塞的模式。读写事件就绪之后,用户自己进行读写,这个读写过程也是阻塞的 | 一些场景下异步IO影响系统的一致性 |
这道题涉及的场景比较多,准备面试的时候选择其中一两点回答即可,但如果时间充足,完全可以把能想得到的都准备一下~
异步网络模型通常涉及非阻塞的事件驱动机制,允许系统在等待某些操作完成的同时执行其他任务。以下是一些应用场景:
①网络编程:Web 服务器:异步模型可用于处理大量并发的网络请求,提高服务器的性能和吞吐量。实时通信:即时通信应用程序,如聊天应用和在线游戏,可以通过异步模型实现实时性和低延迟。
②数据库访问:数据库查询:异步数据库访问可确保在等待数据库响应时不会阻塞整个应用程序,提高数据库查询效率。大数据处理:在处理大规模数据集时,异步模型可以提高数据处理的效率。
③分布式系统:消息传递:异步通信在分布式系统中广泛应用,通过消息传递实现不同组件之间的松耦合通信。事件驱动架构:异步模型适用于构建事件驱动的分布式系统,能够更灵活地处理分布式环境中的事件和任务。
④图形用户界面(GUI)应用程序:用户界面响应性:异步编程可用于确保图形用户界面的响应性,使应用程序在执行长时间任务时不会冻结。
⑤IoT(物联网)应用:传感器数据处理:异步模型适用于处理大量实时传感器数据,以及与物联网设备之间的异步通信。
⑥日志处理和监控系统:日志收集:异步处理可以帮助高效地收集、处理和存储系统产生的大量日志数据。实时监控:异步模型可用于构建实时监控系统,及时检测和响应系统中的异常事件。
异步网络模型在这些场景下的应用可以提高系统的性能、响应性和扩展性,使得系统更好地适应高并发和大规模数据处理的需求。
这道题涉及的场景比较多,准备面试的时候选择其中一两点回答即可,但如果时间充足,完全可以把能想得到的都准备一下~
回调函数: 异步操作可以通过回调函数实现。当一个操作完成时,系统会调用预定义的回调函数,从而实现异步处理。这种模型通常用于事件驱动的编程;
协程: 协程是一种轻量级的线程,可以在运行时暂停和恢复。通过协程,可以编写看似同步的代码,但实际上在执行过程中可以让出控制权给其他任务。Python的asyncio
库就是基于协程的异步编程模型的一个例子;
事件驱动架构: 使用事件和事件处理器的架构可以实现异步编程。当事件发生时,相应的事件处理器被触发执行。这种模型常见于 GUI 编程和分布式系统中;
消息队列: 消息队列系统(如RabbitMQ、Kafka)可以用于在不同组件之间传递消息,实现异步通信。生产者将消息发送到队列,而消费者则异步地接收和处理这些消息;
异步编程可以帮助提高系统的性能和响应性,使得程序能够更有效地处理并发任务和异步操作。
在Java中,同步阻塞和同步非阻塞的实现方式可以通过多线程编程和Java NIO(New I/O)来实现。(面试中只回答到这里)
同步阻塞(Synchronous Blocking):在同步阻塞模型中,当一个线程发起一个请求时,它会被阻塞直到操作完成。这是传统的阻塞I/O模型,通常使用`InputStream`和`OutputStream`等类。
import java.io.*;
public class SyncBlockingExample {
public static void main(String[] args) {
try {
InputStream inputStream = new FileInputStream("input.txt");
int data;
while ((data = inputStream.read()) != -1) {
// 处理数据
System.out.print((char) data);
}
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在上面的例子中,`inputStream.read()`是一个同步阻塞的操作,如果没有数据可读,线程将被阻塞直到数据到达。
同步非阻塞(Synchronous Non-Blocking):同步非阻塞模型通常涉及使用`java.nio`包中的`Selector`、`Channel`和`Buffer`等类,这是Java NIO的一部分。通过选择器(Selector)和通道(Channel),可以实现非阻塞I/O操作。
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
public class SyncNonBlockingExample {
public static void main(String[] args) {
try {
Path filePath = Paths.get("input.txt");
FileChannel fileChannel = FileChannel.open(filePath, StandardOpenOption.READ);
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (fileChannel.read(buffer) > 0) {
buffer.flip();
// 处理数据
while (buffer.hasRemaining()) {
System.out.print((char) buffer.get());
}
buffer.clear();
}
fileChannel.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
在上面的例子中,`fileChannel.read(buffer)`是一个同步非阻塞的操作。如果没有数据可读,它不会阻塞线程,而是返回零。程序通过轮询来检查是否有数据,以确保非阻塞。
①解析url,生成发送给web服务器的请求信息;② 通过dns域名解析,查询服务器域名对应的ip地址,它首先会去自己的缓存中找,如果没有会从根域名服务器,顶级域名服务器,权威域名服务器依次确定;③获取到ip后,会把http的传输工作交给操作系统的协议栈去完成;④建立三次握手;⑤委托IP模块将数据封装成网络包发送给通信对象;⑥在两点之间传输,需要加上mac头部;⑦利用网卡将数字信息转换为电信号,然后在网线上传输;⑧随后经过交换机、路由器到达下一个位置;⑨抵达服务器之后,会依次扒开mac头部、ip头部、tcp头部,得到这个请求是访问一个页面或者什么之后,把它封装到HTTP响应报文里;⑩随后依据上述路线在返回至客户端,扒皮后得到响应报文,交给浏览器去渲染页面;最后看是否是长连接,如果不是,就发起四次挥手,断开连接。
长连接(Long Polling)是一种在客户端和服务器之间保持持久连接的通信方式,以便实时推送数据。有几种实现长连接的常见方式:
①WebSocket:WebSocket是一种在单个TCP连接上进行全双工通信的协议,它允许在客户端和服务器之间进行实时双向通信。通过WebSocket,客户端和服务器可以保持连接开放,从而能够实时地向对方发送消息。在Java中,可以使用Java API for WebSocket(JSR-356)或第三方库(如Netty)来实现WebSocket。
②轮询(Polling):轮询是一种比较简单的长连接模型,客户端定期向服务器发送请求,查询是否有新的数据。客户端发送请求后,如果没有新数据,服务器可能会阻塞连接,直到有新数据为止,或者返回一个空响应表示没有更新。尽管轮询是一种比较简单的实现方式,但由于频繁的请求可能导致不必要的网络开销。
请求行,请求头,请求数据;
请求行中主要有请求url地址,请求方法
请求头常见的主要有:Content-lenth,Content-type,Connection
具体更详细的可查看这个链接哦:一个http请求包含哪几部分内容
这里只列最常见的,面试的时候能把下面的答上就已经足够了~
Accept:指定客户端能够接收的内容类型;
Authorization:HTTP授权的授权证书;
Connection:表示是否需要持久连接。(HTTP 1.1默认进行持久连接)
Cookie:HTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器。
Content-Length:请求的内容长度;
Content-Type:请求的与实体对应的MIME信息;
If-Match :只有请求内容与实体相匹配才有效;
If-None-Match:如果内容未改变返回304代码,参数为服务器先前发送的Etag,与服务器回应的Etag比较判断是否改变
1xx:目前是协议处理的中间阶段,还需要后续的操作
2xx:成功,报文已经收到并被正确处理
3xx:重定向,资源发生变动,需要客户端重新发起请求
4xx:客户端错误
5xx:服务端错误
401指用户缺少认证,403则是指认证成功,但是用户没有被授权操作
500指服务器遇到错误,无法完成请求
502指服务器自身工作正常,但是访问后端服务器发生错误
通过Thread继承,实现Runnable接口,实现Callable接口,线程池创建
java只支持单继承,如果继承thread类,就不能继承别的类,但是可以实现多个接口,其他还有一些面向对象的思想,Runnable就相当于一个作业,而Thread才是真正的处理线程,我们需要的只是定义这个作业,然后将作业交给线程去处理,这样就达到了松耦合,也符合面向对象里面组合的使用,另外也节省了函数开销,继承Thread的同时,不仅拥有了作业的方法run(),还继承了其他所有的方法。综合来看,用Runnable比Thread好的多。
list,set,queue,map,还有并发包里的concurrent开头的,copyonright开头的
详细的可以看这个uu的博客:详细的集合框架概述